惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
T
Threatpost
N
News and Events Feed by Topic
PCI Perspectives
PCI Perspectives
V2EX - 技术
V2EX - 技术
D
Docker
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
The GitHub Blog
The GitHub Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Y
Y Combinator Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
T
Troy Hunt's Blog
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
量子位
Apple Machine Learning Research
Apple Machine Learning Research
H
Help Net Security
F
Full Disclosure
B
Blog
O
OpenAI News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园_首页
Google DeepMind News
Google DeepMind News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security
Know Your Adversary
Know Your Adversary
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
Scott Helme
Scott Helme
T
The Exploit Database - CXSecurity.com
博客园 - 聂微东
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
Recorded Future
Recorded Future
IT之家
IT之家
Project Zero
Project Zero
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
Attack and Defense Labs
Attack and Defense Labs
L
Lohrmann on Cybersecurity
SecWiki News
SecWiki News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

VictoriaMetrics: Simple & Reliable Monitoring for Everyone on VictoriaMetrics

Operator now has Long-Term Support (LTS) version Multi-tiered Observability: A Practical Way to Handle Diverse Workloads VictoriaMetrics April 2026 Ecosystem Updates Not All Telemetry Requires Premium Pricing VictoriaMetrics at KubeCon Amsterdam: Community Highlights What's new in VictoriaMetrics Anomaly Detection (Q1 2026) What's New in VictoriaMetrics Cloud Q1 2026? Logs, MCP Server, Better Alerting, and... a Secret Project VictoriaMetrics at KubeCon: Optimizing Tail Sampling in OpenTelemetry with Retroactive Sampling VictoriaMetrics March 2026 Ecosystem Updates Observability Lessons From OpenAI Benchmarking Kubernetes Log Collectors: vlagent, Vector, Fluent Bit, OpenTelemetry Collector, and more VictoriaMetrics February 2026 Ecosystem Updates VictoriaMetrics at FOSDEM, Cloud Native Days France, and CfgMgmtCamp Ghent VictoriaLogs in VictoriaMetrics Cloud: Fast, Cost-Effective Log Management is Here What’s new in VictoriaMetrics Anomaly Detection (2025) VictoriaMetrics January 2026 Ecosystem Updates VictoriaLogs Basics: What You Need to Know, with Examples & Visuals What's New in VictoriaMetrics Cloud Q4 2025? New tiers, more deployment options, IaC and alerting rules. Vibe coding tools observability with VictoriaMetrics Stack and OpenTelemetry How a US Software Provider Improved Traffic Alerting with VictoriaMetrics Anomaly Detection VictoriaMetrics 2025 Developer Experience: A Year in Review Spotify’s performance & control across large monitoring environments with VictoriaMetrics VictoriaMetrics Achieves Red Hat OpenShift Operator Certification Our latest updates across the VictoriaMetrics Observability ecosystem New Capacity Tiers in VictoriaMetrics Cloud Announcing 1B+ Downloads & Product Development With Logs, Traces, Metrics AI Agents Observability with OpenTelemetry and the VictoriaMetrics Stack What's New in VictoriaMetrics Cloud Q3 2025? From new region in Asia to proactive alerts How DreamHost Slashed Memory Usage by 80% and Scaled to 76 Million Time Series Upcoming Conferences & Meetups: Where to Meet Our Team VictoriaMetrics Long-Term Support (LTS): H2 2025 Update Creating a Sustainable Open Source Business Model - Introduction Full-Stack Observability with VictoriaMetrics in the OTel Demo Alerting Best Practices vmanomaly Deep Dive: Smarter Alerting with AI (Tech Talk Companion) VictoriaLogs Practical Ingestion Guide for Message, Time and Streams Monotonic and Wall Clock Time in the Go time package Hello Singapore! VictoriaMetrics Cloud Expands to Asia Pacific MCP Server Integration & Much More: What's New in VictoriaMetrics Cloud Q2 2025 FIPS 140-3 Compatible Builds for VictoriaMetrics Enterprise Components VictoriaLogs Unleashed: Cluster Version Now Available for Exceptional, Linear Scaling Integrations made easy with VictoriaMetrics Cloud Developer's Note: Research on Distributed Tracing, Comparing With Tempo and ClickHouse vmagent: Key Features Explained in Under 15 Minutes Go synctest: Solving Flaky Tests vmalert: Maximize Your Monitoring (Tech Talk Companion) Celebrating 14K Stars on GitHub: Spring Update vmalert: Maximize Your Monitoring VictoriaMetrics Connects with the Open Source Community at LinuxFest Northwest 2025 Graceful Shutdown in Go: Practical Patterns VictoriaLogs: Gaps, Gains & Growth Prometheus Monitoring: Functions, Subqueries, Operators, and Modifiers VictoriaMetrics Cloud: What's New in Q1 2025? Don’t default to microservices: You’ll thank us later! Container CPU Requests & Limits Explained with GOMAXPROCS Tuning gRPC in Go: Streaming RPCs, Interceptors, and Metadata From Chaos to Clarity with VictoriaLogs Prometheus Alerting 101: Rules, Recording Rules, and Alertmanager Heading to London: Meet Our Team at KubeCon Europe 2025 Inside vmselect: The Query Processing Engine of VictoriaMetrics Meet Our Team at Scale 22x Practical Protobuf - From Basic to Best Practices VictoriaLogs Status Update: Heading Towards the Cluster Version 24th of February 2025 Statement: VictoriaMetrics Stands with Ukraine! Prometheus Metrics Explained: Counters, Gauges, Histograms & Summaries Prometheus Monitoring: Instant Queries and Range Queries Explained 300%+ Growth in 2024: Join Our Team in 2025! FOSDEM 2025 recap How Protobuf Works—The Art of Data Encoding OpenTelemetry, Prometheus, and More: Which Is Better for Metrics Collection and Propagation? How vmstorage Handles Query Requests From vmselect How vmstorage's IndexDB Works VictoriaMetrics Tech Talk Stream: A Deep Dive into Blackbox Monitoring How HTTP/2 Works and How to Enable It in Go VictoriaMetrics Cloud: What's New in Q4 2024? How vmstorage Processes Data: Retention, Merging, Deduplication,... How vmstorage Handles Data Ingestion From vminsert When Metrics Meet vminsert: A Data-Delivery Story From net/rpc to gRPC in Go Applications VictoriaMetrics helps IHI Terrasun Win Big in Vegas on $1.2B Clean Energy Project Piros | VictoriaMetrics Partner Allenta | VictoriaMetrics Partner CloudRaft | VictoriaMetrics Partner Sensedia & VictoriaMetrics: API-compatible Efficient Storage Scalable Prometheus: Why DSV Chose VictoriaMetrics Sensor Factory | VictoriaMetrics Partner Erythix | VictoriaMetrics Partner Groove X & VictoriaMetrics: Faster Device Health Monitoring Scaled & Performant Monitoring at Spotify with VictoriaMetrics Grammarly & VictoriaMetrics: 10× Lower Costs & Direct Access Zelarsoft | VictoriaMetrics Partner DFKI & VictoriaMetrics: Efficient Long-Term Metric Storage Niubits | VictoriaMetrics Partner Megazone Cloud | VictoriaMetrics Partner Cogito Software | VictoriaMetrics Partner Bajau | VictoriaMetrics Partner Find Out Why Dig Security Chose VictoriaMetrics! Ness | VictoriaMetrics Partner Alpha Data | VictoriaMetrics Partner SIOS Technology | VictoriaMetrics Partner
Discarding gRPC-Go: The Story Behind OTLP/gRPC Support in VictoriaTraces
Zhu Jiekun · 2025-10-27 · via VictoriaMetrics: Simple & Reliable Monitoring for Everyone on VictoriaMetrics

Let’s begin with the results we achieved by discarding the use of gRPC-Go to build the gRPC server for OTLP/gRPC:

  • Binary size: -25%
  • CPU usage: -36%

Background

#

The OpenTelemetry protocol (OTLP) is very popular for exchanging telemetry data between any OpenTelemetry instrumented applications and OpenTelemetry (compatible) collectors/backends.

Assume you have an application/collector which want to export data to another collector, you can config it to send data with:

  • OTLP/gRPC exporter
  • OTLP/HTTP exporter, with protobuf payloads encoded in:
    • binary format
    • JSON format

Currently, VictoriaTraces only exposes an HTTP endpoint to receive data via the latter 2 formats: OTLP/HTTP binary & JSON. There are a lot of applications out there that only support sending data via OTLP/gRPC, one typical example could be kube-apiserver. So it’s important to cover these cases as well.

Supporting OTLP/gRPC

#

The Goal

#

Our goal is to provide a gRPC server that can serve as a TraceService and provide the Export method for invocation, as defined in the OpenTelemetry’s proto.

// Service that can be used to push spans between one Application instrumented with
// OpenTelemetry and a collector, or between a collector and a central collector (in this
// case spans are sent/received to/from multiple Applications).
service TraceService {
  rpc Export(ExportTraceServiceRequest) returns (ExportTraceServiceResponse) {}
}

What makes us consider not using gRPC-Go, or to be more specific, not using the protoc toolchain?

Problem 1: The protoc Toolchain Isn’t User-Friendly

#

The common way to build a gRPC server is:

  • Use protoc and protoc-gen-go to generate the structs of the messages defined in .proto.
  • Use protoc and protoc-gen-go-grpc to generate the service interface defined in .proto.

But, wait. Let’s recall how it could be done. Assume I (who is new to the Protobuf) just cloned the project, and want to add new messages/methods to the .proto:

  1. Notice that the protoc toolchain is not part of my Ubuntu/MacOS.
  2. Download the latest version of protoc from the release page.
  3. Ooops, protoc can’t run solely if I want to generate go code. I need to go install protoc-gen-go and go install protoc-gen-go-grpc.
  4. All set, what’s the commands and flags to generate them? Google “gRPC compile Go” for the tutorial.
  5. Finally, I prepared the commands and run it locally. Bomb, it said dependency errors, because there are some imports in my .proto and I have to specify the paths.
  6. After fixing them, rerun the commands and successfully generate (thousands of lines of) Go code.

But don’t jump for joy too soon, because protoc may have unexpected surprises in store for you.

“Why do the new code look different from the previous ones?”

The new one is like:

type TracesData struct {
	state protoimpl.MessageState `protogen:"open.v1"`

	ResourceSpans []*ResourceSpans `protobuf:"bytes,1,rep,name=resource_spans,json=resourceSpans,proto3" json:"resource_spans,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

While the previous one is like:

type TracesData struct {
    ResourceSpans        []*ResourceSpans `protobuf:"bytes,1,opt,name=resource_spans,proto3" json:"resource_spans,omitempty"`
    XXX_NoUnkeyedLiteral struct{}         `json:"-"`
    XXX_unrecognized     []byte           `json:"-"`
    XXX_sizecache        int32            `json:"-"`
}
  1. Google for the reason, then redo steps 2-6 using a different version of the protoc toolchain. (Sometimes you may need to git log to find out who the author of this code.)

All these steps show that compiling protobuf-related stuff is not as straightforward as writing simple HTTP JSON APIs.

It could become easy if you:

  1. Write commands into the Makefile.
  2. Use Buf CLI to compile without the protoc toolchain.

But many developers still opt for the HTTP JSON APIs.

That said, this hardly suffices to persuade us to discard the protoc toolchain. What else?

Problem 2: The Existing Use of easyproto Instead of golang/protobuf

#

Problems 2 may provide further insights, though it should be clarified that it only apply to VictoriaTraces given its unique context.

In VictoriaMetrics, VictoriaLogs and VictoriaTraces, we use easyproto to marshal and unmarshal protobuf messages. The reasons are written in its README:

  • easyproto doesn’t require protoc or go generate.
  • easyproto doesn’t increase the binary size unlike traditional protoc-compiled code may do.
  • easyproto allows writing zero-alloc code.

However, to add OTLP/gRPC support, we need to consider the following:

  1. If we simply build a gRPC server with code generated by protoc, how much will the binary size of the application increase?
  2. Can we combine easyproto with gRPC? This way, protoc would only need to generate code for the gRPC service, and not for protobuf message structs.
    • Note that this still requires importing gRPC-related packages, which weakens the second reason of using easyproto (aimed at reducing binary size).
  3. Are there any other solutions that reuse easyproto without importing new packages?

Unorthodox Way: An HTTP/2 Server

#

The Theory

#

gRPC is a protocol that uses HTTP/2. So it’s possible to implement an HTTP/2 server to serve requests at specific endpoints.

gRPC can also use HTTP/3 (QUIC) and HTTP/1.1, but let’s avoid getting too deep into that for now. Just note that the current implementation also supports gRPC over HTTP/1.1. What’s more, thanks to its highly straightforward design, the OTLP/gRPC JSON format could also be supported very easily. But as the JSON format currently only works with OTLP/HTTP, we haven’t put extra effort into it.

We’ll leave it to readers to explore further.

According to gRPC over HTTP2, the data frame format is like:

// +------------+---------------------------------------------+
// |   1 byte   |                 4 bytes                     |
// +------------+---------------------------------------------+
// | Compressed |               Message Length                |
// |   Flag     |                 (uint32)                    |
// +------------+---------------------------------------------+
// |                                                          |
// |                   Message Data                           |
// |                 (variable length)                        |
// |                                                          |
// +----------------------------------------------------------+

And the HTTP endpoint for Export method in TraceService is: /opentelemetry.proto.collector.trace.v1.TraceService/Export.

The following code block shows you how the implementation looks like:

// Init initializes an HTTP server.
func Init() {
	logger.Infof("starting OTLP gPRC server at :4317...")
	go httpserver.Serve(
		[]string{":4317"},
		OTLPGRPCRequestHandler,
		httpserver.ServeOptions{UseProxyProtocol: nil, DisableBuiltinRoutes: true, EnableHTTP2: true},
	)
}

// OTLPGRPCRequestHandler is the router of gRPC requests.
func OTLPGRPCRequestHandler(r *http.Request, w http.ResponseWriter) bool {
	switch r.URL.Path {
	case `/opentelemetry.proto.collector.trace.v1.TraceService/Export`:
		otlpExportTracesHandler(r, w)
	default:
		grpc.WriteErrorGrpcResponse(w, grpc.StatusCodeUnimplemented, fmt.Sprintf("gRPC method not found: %s", r.URL.Path))
	}
	return true
}

// otlpExportTracesHandler handles OTLP export traces requests.
func otlpExportTracesHandler(r *http.Request, w http.ResponseWriter) {
	// decompression with gzip
    ...

    // verify headers (5 bytes), and unmarshalling the rest bytes with easyproto
    ...

    // presisting data, and more
    ...

	writeExportTraceServiceResponse()
}

The complete code could be found in VictoriaTraces #59.

What’s the Cost

#

While the implementation looks straightforward and simple, there must be a cost.

So far this approach has only been tested with the unary RPC. For streaming RPC, we have no scenarios or motivation for further testing.

This approach can cover what we need for OTLP/gRPC, but it might not work for other cases. If you know more about that, feel free to leave a comment!

Comparison

#

We conduct the benchmark against binary size and resource usage between different approaches of OTLP/gRPC support in VictoriaTraces:

  1. Write an HTTP/2 server, and unmarshal with easyproto.
  2. Compile an gRPC server with protoc, and unmarshal with the native gRPC decoder.

Additionally, the compiled gRPC server does support customizing encoder and decoder via the following code example. We add this to the comparison as well.

import (
	"google.golang.org/grpc/encoding"
)

func init() {
	encoding.RegisterCodec(&easyProtoCodec{})
}

And here’s the result.

For build size:

And regarding the performance of request handling (CPU usage, no-op: requests are responded immediately after decompressing and unmarshalling):

The monitoring snapshot can be found here. CPU and memory profiles are available here.

Based on the benchmark results, it is evident that HTTP/2 combined with easyproto does demonstrate a clear advantage.

Conclusion

#

This blog shares the story why VictoriaTraces implements gRPC server for OTLP/gRPC in the HTTP/2 + easyproto way. The core implementation was done by @JayiceZ, with the initial idea coming from @makasim.

There are certain contextual reasons behind this, we’re not try to persuade you to do so. But we see great potential and value, and better developer experience in this approach.

As the VictoriaMetrics Stack aims for high performance and cost efficiency, every bit of saved CPU, memory, and network traffic matters significantly. And the same holds true for binary sizes, Docker image sizes, and other aspects, just as mentioned in this blog by Aliaksandr Valialkin (founder of VictoriaMetrics), and they remain as critical today as they were then.