Why Go for Microservices?
Fast startup
Compiled binary starts in milliseconds. No JVM warmup, no interpreter.
Low memory
A Go microservice uses 10-50MB. A Java equivalent uses 200-500MB.
Single binary
Deploy one file. No runtime dependencies, no package managers.
Built-in concurrency
Handle thousands of concurrent requests with goroutines.
gRPC
// user.proto
syntax = "proto3";
package user;
service UserService {
rpc GetUser(GetUserRequest) returns (User);
rpc ListUsers(ListUsersRequest) returns (stream User);
}
message GetUserRequest { int32 id = 1; }
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
Docker Multi-Stage Build
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server
FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
Final image: ~10MB (vs 200MB+ for a typical Node.js or Java image). The scratch base image contains nothing — just your binary.
Key Takeaway: Go's single-binary deployment + tiny Docker images + fast startup make it ideal for microservices and Kubernetes. Use gRPC for internal service communication, HTTP/JSON for external APIs.
gRPC Communication
Client
Go/Python/Java
→
Protobuf
serialize
→
HTTP/2
transport
→
Server
Go service
→
Response
protobuf
Practice Exercises
Hard Production Scenario
Design a solution using these concepts for a real-world production system.
Hard Performance Analysis
Benchmark two different approaches and explain which is better and why.