---
title: "Summary: Reflection Removal Evaluation"
---

**Issue**: [FEATURE] Remove reflect  
**Date**: 2026-02-03  
**Status**: EVALUATION COMPLETE - RECOMMENDATION AGAINST REMOVAL

## Executive Summary

After comprehensive analysis of go-micro's reflection usage and comparison with livekit/psrpc (the referenced example), **we recommend AGAINST removing reflection from go-micro**. 

## Key Findings

### 1. Reflection is Fundamental to go-micro's Architecture

Reflection enables go-micro's core value proposition:
```go
// Simple, idiomatic Go - no proto files, no code generation
type MyService struct{}

func (s *MyService) SayHello(ctx context.Context, req *Request, rsp *Response) error {
    rsp.Message = "Hello " + req.Name
    return nil
}

server.Handle(server.NewHandler(&MyService{}))
```

This **requires** reflection. There is no way to achieve this simplicity with generics or code generation.

### 2. livekit/psrpc Uses a Completely Different Architecture

psrpc avoids reflection through **code generation from proto files**:

1. Write `.proto` service definitions
2. Run `protoc --psrpc_out=.` to generate code
3. Implement generated interfaces
4. Register via generated registration functions

This is fundamentally incompatible with go-micro's "register any struct" design.

### 3. Performance Impact is Negligible

- **Reflection overhead**: ~50μs per RPC call
- **Typical RPC latency**: 1-10ms (network) + 0.1-0.5ms (serialization) + business logic
- **Reflection as % of total**: <5% for typical workloads
- **Would removing it help?**: Only for applications with <100μs latency requirements and >100k RPS

### 4. Removal Would Be a Breaking Change

To remove reflection, go-micro would need to:

1. Adopt proto-first design (like gRPC/psrpc)
2. Require code generation for all handlers
3. Change all registration APIs
4. Break all existing applications
5. Estimated effort: 6-12 months of development

### 5. Alternatives Already Exist

Users who need maximum performance and can accept code generation can use:

- **gRPC**: Industry standard, excellent tooling
- **psrpc**: Pub/sub-based RPC without reflection
- **Twirp**: Simple HTTP/Protobuf RPC

go-micro serves a different use case: **rapid development with minimal boilerplate**.

## Deliverables

1. **[reflection-removal-analysis.md](reflection-removal-analysis.md)**
   - 16KB technical deep-dive
   - Code examples showing current reflection usage
   - Comparison with psrpc architecture
   - Detailed feasibility analysis
   - Performance measurements
   - Recommendation with rationale

2. **[performance.md](performance.md)**
   - 6KB user-facing guide
   - When reflection matters (rarely)
   - Performance best practices
   - When to consider alternatives
   - Benchmarks in context

3. **README.md updates**
   - Added link to performance documentation

## Recommendation

**CLOSE THE ISSUE** with the following explanation:

> After thorough evaluation comparing go-micro with livekit/psrpc and analyzing the feasibility of removing reflection, we've determined this would require a fundamental architectural redesign incompatible with go-micro's goals.
>
> **Key findings**:
> 
> 1. **psrpc avoids reflection through code generation** - Requires `.proto` files and generated interfaces, a completely different architecture from go-micro
> 
> 2. **go-micro's strength is "register any struct"** - This requires runtime type introspection (reflection) and cannot be achieved with Go generics or code generation
> 
> 3. **Reflection overhead is ~50μs per RPC**, typically <5% of total latency in real-world applications where network I/O (1-10ms) and business logic dominate
> 
> 4. **Removing reflection would**:
>    - Break all existing code (100% breaking change)
>    - Require 6-12 months of development
>    - Eliminate go-micro's key advantage (simplicity)
>    - Provide <5% performance improvement for most users
> 
> 5. **For users needing maximum performance**, alternatives already exist:
>    - gRPC (industry standard with code generation)
>    - psrpc (pub/sub RPC without reflection)
>    - Direct use of transport layer
> 
> **Documentation added**:
> - [reflection-removal-analysis.md](reflection-removal-analysis.md) - Detailed technical analysis
> - [performance.md](performance.md) - Performance best practices and when to consider alternatives
> 
> **Recommendation**: Keep reflection as a deliberate architectural choice that enables go-micro's simplicity and developer productivity. Profile before optimizing, and consider code-generation-based alternatives (gRPC/psrpc) only if profiling proves reflection is genuinely a bottleneck.
>
> Closing as "won't fix" - reflection is an intentional design decision, not a technical limitation.

## Next Steps

1. Add this comment to the original issue
2. Close the issue as "won't fix"
3. Consider adding a FAQ entry about reflection and performance
4. Link to the new documentation from the main website

## References

- Original issue: [FEATURE] Remove reflect
- livekit/psrpc: https://github.com/livekit/psrpc
- Go Reflection: https://go.dev/blog/laws-of-reflection
- gRPC-Go: https://github.com/grpc/grpc-go

---

**Prepared by**: GitHub Copilot Agent  
**Review**: Ready for maintainer decision  
**Impact**: Documentation only, no code changes
