Go na borda: Construindo aplicações leves para IoT e edge computing

A nuvem é maravilhosa – até que você precisa processar dados de milhares de sensores em tempo real, com latência de milissegundos, em locais sem internet de qualidade. É aí que a computação de borda (edge computing) entra em cena: dados processados perto de onde são gerados, não em datacenters distantes.

Mas dispositivos de borda são limitados: pouca RAM, CPU modesta, armazenamento reduzido. Python é pesado. C/C++ é poderoso, mas complexo e propenso a erros de memória. A linguagem que vem se destacando nesse nicho é Go.

Go oferece o melhor dos dois mundos: performance próxima ao C, com segurança de memória e produtividade. E seu binário estático e compilação cruzada tornam o deploy em dispositivos ARM (Raspberry Pi, gateways industriais, drones) trivial.

Neste post, vamos mostrar como a Jacobus Software utiliza Go em projetos de IoT e edge computing, desde sensores agrícolas até gateways logísticos.

O desafio da programação em dispositivos de borda

Dispositivos de borda têm restrições severas:

RecursoLimite típicoImplicação
RAM128MB a 512MBLinguagens com runtime grande (Java, Python) sofrem
CPUARM Cortex-A ou M (baixo consumo)Interpretadores dinâmicos são lentos
Armazenamento256MB a 8GBBinários grandes inviabilizam updates
Rede2G/4G/5G esporádicaPreciso de sincronização resiliente
EnergiaBateriaEficiência computação por watt é crítica

Go resolve todos esses pontos:

  1. Binários estáticos e pequenos (5-15MB) – nada de runtime externo.
  2. Garbage collector eficiente para uso moderado de memória.
  3. Concorrência leve (goroutines) para múltiplos sensores.
  4. Compilação cruzada nativa GOOS=linux GOARCH=arm go build.
  5. Baixo consumo de CPU em idle.

Compilação cruzada: o superpoder do Go

Um dos recursos mais subestimados de Go é a compilação cruzada sem complicações. Para gerar um binário para um Raspberry Pi (Linux ARM) a partir do seu notebook:

GOOS=linux GOARCH=arm GOARM=7 go build -o app_arm ./cmd/device

Para dispositivos ainda mais modestos (ARM Cortex-M, sem MMU) – Go tem suporte a GOARCH=arm com GOARM=5/6/7. Para sistemas bare metal mais extremos, tinygo compila Go para microcontroladores com apenas 16KB de RAM.

# Para um Arduino Nano 33 IoT (ARM Cortex-M0)
tinygo build -target arduino-nano33 -o firmware.hex ./main.go

sso significa: você escreve Go uma vez e compila para qualquer dispositivo.

Exemplo prático: Gateway de sensores em Go

Um caso comum: um gateway que coleta dados de sensores (temperatura, umidade, vibração) via serial, MQTT ou Modbus, agrega, e envia para a nuvem quando conectado.

package main

import (
    "context"
    "encoding/json"
    "log"
    "time"
    mqtt "github.com/eclipse/paho.mqtt.golang"
)

type SensorData struct {
    DeviceID    string    `json:"device_id"`
    Temperature float64   `json:"temperature"`
    Humidity    float64   `json:"humidity"`
    Timestamp   time.Time `json:"timestamp"`
}

func main() {
    // Configura MQTT client
    opts := mqtt.NewClientOptions().AddBroker("tcp://broker.local:1883")
    client := mqtt.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        log.Fatal(token.Error())
    }

    // Goroutine para cada sensor
    go readTemperatureSensor(client)
    go readHumiditySensor(client)

    // Mantém o gateway rodando
    select {}
}

func readTemperatureSensor(client mqtt.Client) {
    ticker := time.NewTicker(5 * time.Second)
    for range ticker.C {
        // Leitura do sensor (ex: via I2C, serial)
        temp := readFromSensor()
        data := SensorData{
            DeviceID:    "gateway_01",
            Temperature: temp,
            Timestamp:   time.Now(),
        }
        payload, _ := json.Marshal(data)
        client.Publish("sensors/temperature", 1, false, payload)
    }
}

Este código, compilado para ARM, roda em um Raspberry Pi Zero com 512MB de RAM, coletando dados de dezenas de sensores simultaneamente com goroutines.

Go vs Python na borda: diferença brutal

Teste real (Raspberry Pi 3, leitura de 10 sensores + envio MQTT):

MétricaPython (MicroPython)Go (compilado)
Tempo de inicialização~2 segundos~0.02 segundos
Uso de RAM em idle~20MB (~60MB com CPython)~3MB
CPU em 100 eventos/s45%8%
Tamanho do binárioN/A (script + runtime ~15MB)6MB estaticamente linkado

Em bateria, Go pode durar 3x mais que Python.

Casos de uso reais da Jacobus com Go na borda

1. Monitoramento agrícola (AgTech)

Desafio: Sensores de umidade e temperatura no solo, enviando dados via rádio LoRa para um gateway em fazenda remota sem internet. Gateway precisa armazenar dados em cache local e transmitir quando conectividade aparece (4G esporádico).

Solução em Go:

  • Gateway rodando Go em Raspberry Pi Compute Module 4.
  • Banco de dados embarcado bbolt (key-value, da própria equipe Go) para cache local.
  • Goroutine para coleta via serial, outra para sync com nuvem (AWS IoT Core) quando online.
  • Binário único de 8MB, atualização over-the-air via scp.

Resultado: 6 meses de operação sem reinicialização manual, sincronização confiável, consumo de <2W.

2. Rastreamento logístico de cargas refrigeradas

Desafio: Caminhões transportam cargas sensíveis. Dispositivo de bordo monitora temperatura da cabine, portas abertas, localização GPS. Precisa de baixo custo e resiliente a quedas de energia.

Solução em Go:

  • Dispositivo ESP32 (TinyGo) rodando Go nativo.
  • Coleta de sensores, envio via MQTT para broker no caminhão (Raspberry Pi).
  • Pi agrega dados e envia para a nuvem via 4G.

Resultado: Redução de 40% no custo de desenvolvimento comparado ao C++ tradicional. Time da Jacobus produziu firmware em 3 semanas.

Dicas para projetos Go em IoT

1. Use TinyGo para microcontroladores

TinyGo é um compilador alternativo que gera código para placas como Arduino, ESP32, BBC micro:bit. Suporta um subconjunto da linguagem Go (sem reflect, sem cgo, etc.) – suficiente para muitos cenários.

2. Reduza o tamanho do binário

Para dispositivos com pouco armazenamento:

go build -ldflags="-s -w" -o app
# -s: remove tabela de símbolos
# -w: remove DWARF debug info
# Reduz tipicamente 30-40% do binário

Use upx --brute para compressão adicional (cuidado com tempo de descompressão em CPUs lentas).

3. Evite alocações frequentes no heap

Em dispositivos com pouca RAM, o GC pode causar pausas. Prefira:

  • Buffers reusados (sync.Pool)
  • Arrays estáticos vs slices
  • Evite concatenar strings com + (use strings.Builder)

4. Use canais com cuidado

Goroutines são leves, mas cada canal tem overhead. Para sensores de alta frequência, use lock-free structures ou atomic quando possível.

Desafios e limitações de Go em IoT

  • Suporte a drivers periféricos: Ainda menos bibliotecas para I2C, SPI, GPIO que C/C++. Mas o ecossistema cresce (ex: periph.io, go.bug.st/serial).
  • TinyGo tem limitações: Nem toda biblioteca padrão funciona. Verifique compatibilidade antes de escolher.
  • Depuração remota limitada: gdb funciona, mas não é tão maduro quanto em C.

Ainda assim, para 80% dos projetos de edge computing (gateways, agregadores, dispositivos Linux-based), Go é imbatível.

Conclusão: Go é a linguagem da borda

A computação de borda veio para ficar. Dispositivos inteligentes não podem esperar a ida e volta até a nuvem. Go oferece a combinação perfeita para esse novo mundo: performance, simplicidade, binários pequenos e estáticos, e compilação cruzada nativa.

Na Jacobus Software, já entregamos projetos de IoT em fazendas, frotas e fábricas usando Go. Se você tem sensores, dispositivos ou gateways, Go pode ser a diferença entre um protótipo quebradiço e um sistema que realmente escala.

O futuro do software não está só na nuvem. Está na borda. E Go é o motor dessa revolução.


📡 Quer levar Go aos seus dispositivos de borda?

Nossos especialistas desenvolvem firmware, gateways e aplicações edge em Go – para Raspberry Pi, ESP32, e outros dispositivos Linux/ARM.

👉 Fale com a Jacobus Software

Rolar para cima