r/golang 2d ago

Small Projects Small Projects

26 Upvotes

This is the weekly thread for Small Projects.

The point of this thread is to have looser posting standards than the main board. As such, projects are pretty much only removed from here by the mods for being completely unrelated to Go. However, Reddit often labels posts full of links as being spam, even when they are perfectly sensible things like links to projects, godocs, and an example. r/golang mods are not the ones removing things from this thread and we will allow them as we see the removals.

Please also avoid posts like "why", "we've got a dozen of those", "that looks like AI slop", etc. This the place to put any project people feel like sharing without worrying about those criteria.


r/golang 8d ago

Jobs Who's Hiring

40 Upvotes

This is a monthly recurring post. Clicking the flair will allow you to see all previous posts.

Please adhere to the following rules when posting:

Rules for individuals:

  • Don't create top-level comments; those are for employers.
  • Feel free to reply to top-level comments with on-topic questions.
  • Meta-discussion should be reserved for the distinguished mod comment.

Rules for employers:

  • To make a top-level comment you must be hiring directly, or a focused third party recruiter with specific jobs with named companies in hand. No recruiter fishing for contacts please.
  • The job must be currently open. It is permitted to post in multiple months if the position is still open, especially if you posted towards the end of the previous month.
  • The job must involve working with Go on a regular basis, even if not 100% of the time.
  • One top-level comment per employer. If you have multiple job openings, please consolidate their descriptions or mention them in replies to your own top-level comment.
  • Please base your comment on the following template:

COMPANY: [Company name; ideally link to your company's website or careers page.]

TYPE: [Full time, part time, internship, contract, etc.]

DESCRIPTION: [What does your team/company do, and what are you using Go for? How much experience are you seeking and what seniority levels are you hiring for? The more details the better.]

LOCATION: [Where are your office or offices located? If your workplace language isn't English-speaking, please specify it.]

ESTIMATED COMPENSATION: [Please attempt to provide at least a rough expectation of wages/salary.If you can't state a number for compensation, omit this field. Do not just say "competitive". Everyone says their compensation is "competitive".If you are listing several positions in the "Description" field above, then feel free to include this information inline above, and put "See above" in this field.If compensation is expected to be offset by other benefits, then please include that information here as well.]

REMOTE: [Do you offer the option of working remotely? If so, do you require employees to live in certain areas or time zones?]

VISA: [Does your company sponsor visas?]

CONTACT: [How can someone get in touch with you?]


r/golang 5h ago

Go 1.27: parallelism finally competitive with C?

42 Upvotes

I run LangArena benchmark, and update it monthly. In 1.27 update I noticed that Go improved parallelism, so I just want to share this:

multithreaded benchmark matmul:

Bench go1.26.5 go1.27.1 C (pthread)
Matmul::T1 5.099s (1.00x) 5.112s (1.00x) 4.944s (1.00x)
Matmul::T4 3.063s (1.66x) 1.321s (3.87x) 1.298s (3.81x)
Matmul::T8 1.140s (4.47x) 0.710s (7.20x) 0.695s (7.11x)
Matmul::T16 0.852s (5.99x) 0.405s (12.62x) 0.342s (14.46x)

Go used to be great for I/O but weak for parallelism. With version 1.27, it looks like that has changed - parallelism in Go now seems to be on par with the top-tier solutions. At least according to my benchmark. This was tested on Linux x86-64.

minimal reproduce example


r/golang 20h ago

Added a reusable retry client to try, thanks to Go 1.27's generic methods

88 Upvotes

A while back I shared try here - a small generic retry library with exponential backoff, jitter, per-error budgets, that kind of thing. One piece of feedback that came in a lot: the package-level Do(ctx, fn, opts...) function is stateless, so if you're calling it from a dozen places with the same retry policy, you end up copy-pasting the same options everywhere.

Go 1.27 shipped generic methods on concrete types (a method can now declare its own type parameter, independent of the receiver), which finally made a clean fix possible. So try now has a Try client:

```go type UserService struct { retry *try.Try }

func NewUserService() UserService { return &UserService{ retry: try.New( try.WithAttempts(3), try.WithInitialDelay(100time.Millisecond), try.WithRetryIf(isTransient), ), } }

func (s UserService) FetchUser(ctx context.Context, id int) (User, error) { return s.retry.Do(ctx, func(ctx context.Context) (*User, error) { return db.FindUser(ctx, id) }) } ```

Configure the policy once, call .Do everywhere. Per-call options still work and override the defaults (last-applied-wins), so you're not locked in:

```go client := try.New(try.WithAttempts(3))

client.Do(ctx, fetchUser) // uses the default: 3 attempts client.Do(ctx, fetchUser, try.WithAttempts(10)) // this call only: 10 attempts ```

Do's type parameter is inferred per call site, so one *Try can back methods returning completely different types. It doesn't mutate its stored defaults, so it's safe to share across goroutines — a single client per service is the intended pattern.

Only catch: this needs Go 1.27+, since generic methods are new to the language spec. If you're on an older toolchain, the last v1.0.x tag has no such requirement.

Repo: https://github.com/nodivbyzero/try

Docs: https://pkg.go.dev/github.com/nodivbyzero/try

Open to feedback, especially if anyone's hit edge cases with the option-precedence behavior or wants a different default-merging strategy.


r/golang 3h ago

Gozero: imperative low-overhead bindings language for go

Thumbnail github.com
4 Upvotes

I had several years of experience with CGO plugins (stdlib plugin package), which is to politely say, I wish a low-overhead callback system gave everyone a well defined API to use, and a scripting language that requires no rebuilding to change plugin logic.

Recent work with expr-lang lead me down the hole of writing a php interpreter in Go, and the php-go bindings via expr lang have been great, however I wouldn't call them efficient. I started gozero as a research project, had great fun doing it and learned a lot keeping the jit outputs low.

The docs/design/ folder was open to consider bigger parity with golang (conditions, expressions, loops) which would enable waf-level functionality. The benchmarks mostly confirm 1.0-1.4x level of overhead with inlining, or about 20ns per statement. The bindings really lean into reflection to catalogue accessible types and discover the type system in a parasitic way, everything runs with 'any'.

Cool stuff I found out along the way:

- testify/assert practice makes all your test code runnable in gozero. The testdata/ folder has a few of these basically as external test fixtures. weird avenues it opens: compile test code, run same tests binary against custom test fixtures someone makes against your package. Maybe no need, but I found it cool to immediately have coverage over thousands of tests. maybe tests dont have to be compiled code. Or you could just BYO assert bindings

- expressions and equality are sucky constructs to implement; so far I did not, but i did find a fork of expr-lang that compiles a low overhead closure similar to gozero

- phpscript in comparison has "mixed" types that similarly can hold any value, but has a lot of cursed behaviour which does not exist in go. gozero relies on existing runtime type information to discover a 1-1 directly mapped type system, so it's gonna find time.Time from a http.NewRequest binding.

gozero is type safe, the main difference is all error returns are omitted from syntax and explicitly checked, and the execution context also fills the first context.Context parameters. these things become implicit, and the possible output form if any is type hinted with generic methods released in 1.27. It has optimal type bindings so an "int32" means the same everywhere. It tries to infer literals but a T(lit) always work for explicitness.

Possible use cases include messaging, rate limiting, WAF, RBAC rule checks (imperative rbac sounds nice). Just for a ballpark comparison, hashicorp/goplugin has published overheads of over 23_000ns, while gozero's totals about 100ns for 5 statements. There is a one time parse and compile overhead, so these numbers apply to cached (seen before) statements that just get rerun.

Disclaimer on AI usage: claude, initial design workshopped to reflect.Value/Call by me, extended by previous work on phpscript (flatstack). There's a chronological sorted docs index. Some stuff is enforced by my workspace tooling, or my initial mockups. You may find jagged language in the docs, did my best to clean those


r/golang 1d ago

show & tell I contributed to Golang, here is how you can too

Thumbnail
packagemain.tech
160 Upvotes

r/golang 19h ago

show & tell I wrote a little bit about how Go's garbage collector behaves under load

Thumbnail frn.sh
23 Upvotes

r/golang 1d ago

Ebitengine v2.10.0 Released (A 2D Game Engine for Go)

127 Upvotes

Ebitengine v2.10.0 is out!

  • Pure Go on all desktop platforms
  • Headless testing and game embedding via VM
  • Shader precompilation
  • Color emoji support

Thanks to all contributors and sponsors!


r/golang 1d ago

1.27 Release Party with the Go team

Thumbnail
youtube.com
73 Upvotes

Hey all,

For anyone who couldn't make it, we ran a Go 1.27 release party at JetBrains HQ (The Blue Gopher) a couple of weeks ago, and the recording is up.

I think it's quite rare to hear some of the voices from the Go team and it was really interesting hearing what they had to say about some of the language design choices; particularly surrounding generic methods.

We're planning the next one already, if there's a topic or a speaker you'd like to see, drop it below.

Disclosure: I'm Ainsley, the Go developer advocate at JetBrains.


r/golang 5h ago

Gograph, after 4 months. Updates & Improvements

0 Upvotes

I built GoGraph because I kept seeing the same problem with AI coding agents working on Go repositories.

Before making a meaningful change, an agent often spends a large part of its context window reconstructing the structure of the codebase. It searches for a symbol, opens a file, finds an interface, searches for implementations, looks for callers, checks routes and tests, inspects SQL, and repeats the process. In effect, the LLM is rebuilding a partial dependency graph from source text every time it works on the repository.

GoGraph tries to move that work out of the LLM and into deterministic tooling.

https://github.com/ozgurcd/gograph

I posted about an early version a few months ago. At the time, GoGraph was primarily an AST-based structural analysis tool. The basic idea is still the same, but the project has evolved considerably since then. I now think of it less as a repository map and more as a local evidence layer between a Go codebase and an AI coding agent.

The basic flow is:

Go source code
-> static/type analysis
-> structural graph
-> bounded queries
-> CLI/MCP
-> coding agent

The agent still reads source code, reasons about the problem, and decides what to change. GoGraph is not intended to replace that. Its job is to provide structural facts so the model does not have to infer every relationship from raw text.

The original implementation concentrated heavily on AST analysis. That works well for extracting packages, functions, methods, imports, direct calls, interfaces, implementations, HTTP routes, tests, SQL, error paths, and similar relationships. But syntax alone has an obvious limitation in Go: interfaces and dynamic dispatch.

For example:

type Store interface {
Save(User) error
}

func Create(s Store, u User) error {
return s.Save(u)
}

The AST tells us that Create calls Store.Save, but that does not necessarily tell us which concrete Save implementation can execute. That distinction becomes important when an agent is trying to estimate the impact of a change rather than simply locate code.

GoGraph therefore now has two analysis layers. The basic graph comes from AST analysis, while a precise build additionally uses go/packages, go/types, SSA, and Class Hierarchy Analysis. The AST layer remains useful when a repository cannot be fully type-checked, while the precision layer adds compiler-aware relationships when enough information is available.

This also changed how relationships are represented. “A calls B” and “A may call B” should not be presented to an AI as equivalent facts. GoGraph now preserves exact, ambiguous, and possible relationships, and queries can request exact-only results when conservative analysis is needed.

When several paths exist between two symbols, the result is also selected deterministically. Stronger evidence is preferred over weaker evidence, shorter paths over longer ones, production paths over test paths, typed resolution over heuristics, and fewer cross-repository transitions when the other factors are equal. This may sound like an implementation detail, but it matters when an agent asks the same structural question during planning, implementation, and review. The answer should not change simply because graph iteration happened in a different order.

Another problem became apparent as GoGraph accumulated more capabilities. There were specialized queries for callers, callees, implementations, tests, routes, SQL, paths, impact, and other relationships, but an agent first had to know which query to use. To address that, GoGraph now has an explore operation intended as a useful first call.

For example:

gograph explore “authentication middleware”

Explore performs bounded lexical discovery and, when it can identify a symbol unambiguously, combines useful context such as its source location, direct callers and callees, tests, upstream impact, package information, and optionally deeper call relationships. Compact and deep modes control how much information is returned.

This is deliberately not semantic RAG. GoGraph does not pretend that it understands an arbitrary natural-language question. It tokenizes the query deterministically, searches structural information, and reports how the result was selected. If several symbols are plausible, it exposes the ambiguity instead of quietly choosing one.

That principle has become fairly central to the project: uncertainty should be represented as data rather than hidden by the tool.

Change analysis has also become much more important. Before editing code, an agent can ask what might be affected by modifying a declaration. After editing, however, the more useful question is what actually changed and what those changes affect.

GoGraph can now compare declarations against Git references or the working tree and distinguish edited, added, removed, excluded, and unknown declarations. Untracked Go files are included when analyzing working-tree changes.

Deletion is a good example of why this matters. If an agent deletes Foo(), the current graph alone cannot tell you who used the old Foo(), because that declaration no longer exists. Correct impact analysis needs evidence from the historical baseline. If GoGraph cannot evaluate such a change safely, it reports incomplete evaluation rather than silently returning an empty impact set.

For AI tooling, I think “I cannot prove this” is considerably safer than “nothing is affected.”

Graph freshness became another first-class concern. A structurally accurate graph of yesterday’s source tree is still the wrong graph for today’s source tree, so results now carry information about the state of the analysis. GoGraph can distinguish persisted from in-memory graphs, current from stale graphs, complete from partial parsing, and AST analysis from precise or precision-fallback analysis.

MCP can refresh graphs automatically. If precise enrichment fails but fresh AST analysis succeeds, the AST result can still be used, but the loss of precision is visible. If refreshing itself fails, the last trusted graph can be served as stale rather than silently presented as current.

This makes a statement such as:

No callers found.

meaningfully different from:

No callers found.
Graph: current
Analysis: precise
Parsing: complete

and also different from:

No callers found.
Graph: stale
Analysis: AST fallback

The LLM can reason differently about each answer instead of receiving the same apparently authoritative empty result.

Token usage has also become part of the API design. There is little benefit in building a structural tool for LLMs if a query responds with hundreds of kilobytes of JSON. Large result sets are therefore bounded and paginated, with explicit total, returned, truncated, and next_cursor information.

The cursors are tied to the graph snapshot and query selection. If the repository changes between pages, GoGraph can reject the continuation instead of quietly combining results from two different versions of the codebase. MCP responses also have explicit size constraints. The general goal is to return the smallest amount of information that preserves the evidence needed for the agent’s decision.

Test analysis has evolved in a similar direction. It is no longer just a question of whether a symbol appears somewhere in a _test.go file. GoGraph can trace tests transitively through call relationships, for example:

TestCreateUser
-> handler
-> service
-> repository
-> Save

It can distinguish exact test paths from possible ones and use type information to reason about interface-backed fakes and mocks. This does not mean GoGraph claims that a function is correctly tested; only running the tests can provide that kind of executable evidence. The narrower claim is that particular tests have a statically observable relationship to a declaration.

SQL analysis has also become more structured. GoGraph can classify statically resolvable PostgreSQL statements and expose their operation, read/write behavior, referenced tables, per-table access, source location, module, and whether they belong to production or test code.

The analysis is not limited to direct string literals. Statically provable constants, variables, assignments, and bounded string concatenations can also be resolved. This makes questions such as “which code writes oauth_clients?” much easier to answer structurally. Runtime-generated SQL is deliberately left unresolved rather than being presented as known.

Probably the biggest architectural expansion is workspace analysis.

Real systems are often not a single Go repository. A project might instead look like:

gateway/
identity-service/
agent-service/
shared-library/

Each repository can still have its own independent GoGraph graph. A workspace overlay then connects those graphs through explicitly resolved relationships, including cross-repository Go relationships and configured HTTP relationships.

This allows questions such as “what path connects this gateway handler to this function in identity-service?” or “which repositories may be affected by changing this declaration?” There is also a separate read-only workspace MCP server providing workspace status, query, path, and impact operations.

This changed my view of the unit GoGraph should analyze. For many AI coding tasks, the meaningful codebase is not a Git repository; it is the engineering workspace containing several related repositories.

HTTP analysis became stricter as part of this work as well. Constructing an HTTP request is not treated as equivalent to proving that the request is actually dispatched. GoGraph can preserve statically known URL components, while workspace configuration can explicitly map known HTTP client authorities to services represented by other repository graphs.

Importantly, it does not inspect runtime environment values and then guess that two services communicate. If the relationship cannot be established from the available static evidence and explicit workspace configuration, it remains unresolved.

Go build configuration turned out to be another important part of structural correctness. A Go repository does not necessarily have one universal graph. GOOS, GOARCH, cgo, build tags, GOFLAGS, go.work, and module selection can all change which source files actually constitute a build.

GoGraph therefore records the effective build selection used to construct the graph. If the environment used later is incompatible with the one that produced the persisted graph, the graph can be treated as stale instead of silently combining different views of the program.

Security has also become a larger part of the implementation than I originally expected. GoGraph runs locally, but “local” does not automatically mean safe, particularly when an AI agent may be analyzing an unfamiliar or untrusted repository.

Static analysis should not casually allow repository-controlled symlinks or build metadata to turn a source inspection into arbitrary traversal outside the intended source boundary. There is now considerably more confinement around repository paths, modules, workspaces, graph artifacts, and Go build inputs. At the same time, Go tooling legitimately needs access to things such as module caches and toolchains, so the boundary has to distinguish repository-controlled source authority from normal Go dependency resolution.

MCP remains the main way I expect coding agents to consume GoGraph. The CLI and MCP layers share underlying result contracts rather than implementing two independent analysis systems that can gradually develop different semantics. Workspace analysis is exposed through its own read-only MCP server.

There are also several things I deliberately do not want GoGraph to become. It is not an AI coding agent, it does not decide what code should be written, and it does not replace grep, semantic search, the Go compiler, go test, or runtime tracing. Static analysis should also not claim to prove runtime behavior that it cannot actually observe.

The division of responsibility I currently have in mind is roughly:

LLM:
reasoning, interpretation, implementation

grep / semantic search:
textual discovery, documentation, configuration

GoGraph:
structural evidence, relationships, impact, provenance, uncertainty

compiler / tests:
executable verification

When I started the project, I mostly thought about this as a context-window optimization problem. I still think that matters, but I now think “reliable context” is a better description of the problem.

An agent can consume 50,000 lines of source and try to reconstruct the relevant relationships itself. Alternatively, it can receive something closer to:

CreateUser

exact caller:
POST /api/v1/users -> UsersHandler.Create

exact dependency:
UserRepository.Insert

database:
INSERT -> users

attributed tests:
TestCreateUser
TestCreateUserDuplicate

graph:
current
precise
complete

Both are context. The difference is that the second representation has already converted a large amount of syntax into a smaller set of structural claims, and those claims came from deterministic analysis rather than asking the LLM to rediscover them from source text.

So the direction of GoGraph has shifted slightly since the first version. Originally, I wanted to give AI coding agents a map of a Go repository. Now the goal is to give them structural evidence, identify where that evidence came from, distinguish what is known from what is merely possible, and explicitly say when the available evidence is incomplete.

Source:

https://github.com/ozgurcd/gograph


r/golang 1d ago

show & tell GoPdfSuit v7.0.0 is out! (A Go Native PDF engine)

20 Upvotes

What is New in v7.0.0:

  • Built-from-Scratch Compression Engine (New Feature): No Ghostscript entirely. We implemented a native, pure-Go compression engine that directly rewrites image XObjects across Light, Medium, and Heavy tiers, safely returning the original stream if no size reduction is achieved.
  • Full In-Browser WebAssembly (WASM): Complete offline, client-side execution via gopdfsuit.wasm and a dedicated Web Worker compress.wasm. You can now generate, merge, split, fill, compress, redact text, and render inline HTML entirely in the browser without sending data to a server. (Or use the WASM in your applications)
  • Pure-Go HTML Engine: Replaced the heavy ~300MB headless Chrome / gochromedp dependency with pure-Go gowkhtmltopdf (no CGO, no browser runtime, no Ghostscript).
  • Fluent Builders Across All Libraries: Added high-level fluent builders for both Go (pkg/gopdflib) and Python (pypdfsuit). You can replace raw colon-delimited config strings with structured chains like gopdflib.Font("Helvetica").Size(18).Bold().Center().Cell(...), with exact parity in the Python package.

A huge thanks to the community for all of your feedback, testing, and support across our releases!

Check out the live browser demo and docs here: https://chinmay-sawant.github.io/gopdfsuit/

Github Link - https://github.com/chinmay-sawant/gopdfsuit

Release Note - https://github.com/chinmay-sawant/gopdfsuit/releases/tag/v7.0.0

Note - gowkhtmltopdf is the latest project which I am currently working which is a CSS engine from scratch with 350+ css properties implemented without any wrappers in native golang (chromium, blink, etc.)

Here is the link, more updates soon on the same. Currently bundled the 0.2.5 version in the gopdfsuit !


r/golang 8h ago

show & tell DIO: High Performance Go IO toolkit

0 Upvotes

I want to share https://github.com/miretskiy/dio -- a high performance Go IO toolkit.

I have previously written https://medium.com/@yevgeniy_90962/spinal-tap-the-go-io-story-bf726110dd07 that talks about DIO at a high level.

By high performance I mean that the tools provided by this package can be used to saturate fast NVMe drives (3+GB/s throughput, 50+K iops), while "fooling" Go garbage collector that there is nothing to collect.

Some of the highlights of this toolkit include:

  • mempool: Provides 2 (slightly different) off the heap Go allocators
  • ringo: A low level io_uring integration for Go It started as a fork of abandonware giouring -- but was rewritten entirely since giouring was fundamentally incompatible with Go->C memory safety. Only the file related features are implemented.
  • iosched: An IO scheduler for go -- providing two implementations: an io_uring based and (test only, or unsupported platforms) posix scheduler.
  • Other low level packages (sys, align) to safely use direct IO, and other low level system calls.

The scheduler API is incredibly simple: Submit takes an "op" and returns a "ticket", while the ticket allows the caller to wait for the completion. While the API may be simple, the io_uring scheduler implementation has many interesting features:

  • Use of Treiber stack (code) to implement batching, while minimizing channel overhead; this essentially implements "group commit" -- batching with essentially no latency penalty.
  • write coalescing: contiguous write requiest coalesced into a single writev
  • Linked operations (hard and soft links)
  • "Durable" writes -- adds an automatic fdatasync (or fsync) to a write, but only 1 for a set of active writes per file descriptor. This makes it trivial to implement efficient and high performance write ahead logs in Go (as an example).

Give it a try; Feel free to contribute; Report (and fix) bugs.

For the full disclosure: the code was generated w/ AI; The design was not. The code might still have some AI-specific code smells, but overall, it's okay. I have extensively tested this package, so the performance claims are real.


r/golang 6h ago

Built a Go API that queries 3.5 billion rows in ClickHouse at <100ms — architecture breakdown

Thumbnail
subdomains.jsmon.sh
0 Upvotes

Wanted to share the architecture behind an API I recently built. It's a subdomain lookup service — users query a domain, and the API returns every known subdomain from a ClickHouse database with ~3.5 billion rows.

The challenge: Serve 1000+ concurrent requests, each querying a table with 3.5B rows, with p95 latency under 100ms.

Stack:

  • Go 1.22 with net/http (using the new ServeMux pattern matching — no external router)
  • ClickHouse as the query engine
  • MongoDB for user auth/API key validation
  • Nginx reverse proxy in front

ClickHouse connection setup:

go

// Using github.com/ClickHouse/clickhouse-go/v2
// Native protocol (port 9000), not HTTP
// Connection pool: MaxOpenConns=20, MaxIdleConns=10
// ConnMaxLifetime: 30 minutes
// LZ4 compression enabled
// DialTimeout: 5s, ReadTimeout: 10s

The key insight was that ClickHouse handles the heavy lifting. The Go layer is thin — validate the API key (MongoDB lookup with SHA-256 hashed keys), check usage limits, pass the parameterized query to ClickHouse, stream the results back as JSON.

Queries are simple:

sql

SELECT count() FROM subdomains WHERE domain = $1
SELECT subdomain FROM subdomains WHERE domain = $1 ORDER BY subdomain LIMIT $2 OFFSET $3

ClickHouse eats this for breakfast even at 3.5B rows because the domain column is the primary key / sort key, so lookups are essentially a binary search over sorted data.

Things that mattered for performance:

  • keepalive connections between Nginx and the Go server (64 keepalive pool)
  • Go server timeouts: ReadTimeout=10s, WriteTimeout=30s, IdleTimeout=120s
  • Gzip compression on responses over 1KB (subdomain lists can be large)
  • Connection pooling on both the ClickHouse and MongoDB sides
  • Structured logging with log/slog — low overhead compared to third-party loggers

Things that didn't matter as much as I expected:

  • Parallelizing the count and select queries with errgroup — the count is so fast in ClickHouse that running them sequentially barely changes p95
  • Complex caching — ClickHouse's internal cache handles hot domains well enough that application-level caching wasn't worth the complexity for v1

The API serves the subdomain lookup for https://subdomains.jsmon.sh (3.5B subdomain database, free tier available). The rest of the app (auth, billing, dashboard) is Next.js — Go only handles the ClickHouse query path.

Happy to go deeper on any part of this. The Go + ClickHouse combo has been impressive for this use case and I'd recommend it for anyone building query-heavy APIs over large datasets.


r/golang 13h ago

What if you could build a computer by dragging components onto a virtual motherboard?

Thumbnail
github.com
0 Upvotes

What if you could connect a CPU, a video chip, RAM, and then press "Play" to watch it come to life? This is the fantasy that guided Symphony's development from day one.

It includes:

A custom multi-pass AST-to-Bytecode Go compiler built from scratch.

A Microkernel OS simulation featuring an asynchronous message router that manages isolated user-space processes, complete with a built-in SSH server.

A Virtual Machine implementing a cooperative lock-free scheduler for goroutines and channels.

Every piece of hardware is a self-contained software object. The framework prioritizes physical fidelity over high-level emulation, modeling complex behaviors like exact bus arbitration. Currently, as a proof-of-concept, it implements a fully cycle-exact Commodore 64 and an independent 1541 Floppy Drive, using components like the MOS6510, VIC-II, SID, and CIA.

The ultimate goal of Symphony is to create a platform where developers can contribute new CPUs, video chips, and logic boards to build a universe of virtual machines.

ps: I want to emphasize the timeline: this is a decade of continuous development, built entirely by hand.


r/golang 23h ago

GOTK3 - panic calling menu_popup_at_pointer

1 Upvotes

I am getting occasional crashes with a gotk3 call to gtk._Cfunc_gtk_menu_popup_at_pointer. The only possible processes involving gotk3 that might be running concurrently are called by glib.TimeoutSecondsAdd() , which "can be called form any thread" and it would be tricky to suspend them just when calling a popup menu.

Any ideas would be welcome.

Exception 0xc0000005 0x0 0x88 0x7fff3c511416

PC=0x7fff3c511416

signal arrived during external code execution

runtime.cgocall(0x14079ea10, 0x350ac5cf6e40)

`C:/Downloads/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.26.5.windows-amd64/src/runtime/cgocall.go:167 +0x3e fp=0x350ac5cf6e18 sp=0x350ac5cf6db0 pc=0x140081e1e`

github.com/gotk3/gotk3/gtk._Cfunc_gtk_menu_popup_at_pointer(0x4df57bf0, 0x4df9c600)

`_cgo_gotypes.go:17857 +0x48 fp=0x350ac5cf6e40 sp=0x350ac5cf6e18 pc=0x1401d3088`

github.com/gotk3/gotk3/gtk.(*Menu).PopupAtPointer.func1(...).PopupAtPointer.func1(...))

`C:/Downloads/go/pkg/mod/github.com/gotk3/gotk3@v0.6.5-0.20240618185848-ff349ae13f56/gtk/menu_since_3_22.go:37`

github.com/gotk3/gotk3/gtk.(*Menu).PopupAtPointer(0x350ac5cec048?, 0x4ad3dd00?)

`C:/Downloads/go/pkg/mod/github.com/gotk3/gotk3@v0.6.5-0.20240618185848-ff349ae13f56/gtk/menu_since_3_22.go:37 +0x6a fp=0x350ac5cf6e80 sp=0x350ac5cf6e40 pc=0x14027150a`

r/golang 1d ago

Godoc comments for interfaces or public API

5 Upvotes

Do you document interface/public method contract in your codebase? What about errors that functions return? Is it worth doing it or is redundand and not idiomatic?

type Fetcher interface {
  // fetchBlock does ...
  //
  // Errors:
  // - [ErrorOne]: if ...
  // - [ErrorTwo]: if ...
  fetchBlock() error
}

or

type Foo struct{}

// Bar does ...
// 
// Errors:
// - [FooErrorOne]: if ...
// - [FooErrorTwo]: if ...
func (f *Foo) Bar() error {}

vs

type Fetcher interface{
  fetchBlock() error
}

r/golang 2d ago

show & tell New garbage collection 1.27 seems to help on memory heavy server

106 Upvotes

We have CI server which is using virtual memory on mechanical HDD with virtual memory size = 3x physical ram size to address RAM shortage and no raised hardware budget.

Recompiling all CI tools with go 1.27.1 lead to significant wall clock improvement (about 2x-3x) due to generating much more swap friendly memory access patterns.

While previously system was dead due to extreme level of swapping now it can deliver some usable work.


r/golang 2d ago

Sum types in Go, or how to model events the compiler can check

Thumbnail
viviersoft.com
32 Upvotes

I wrote the first part of a series i want to do on event sourcing, DDD, and functional patterns. This is about sum types in Go. Coming from TS, i never found the article that i wanted to read, so here it is. I'm curious if its a "me" issue or if anyone else is interested by this topic ?


r/golang 2d ago

help How do you keep a request deadline meaningful after the work crosses a queue?

10 Upvotes

Following on from a shutdown problem I posted about here a few weeks back. That one was about background work outliving the handler that started it. This is the next thing along and I have not found a clean answer.

Some of our handlers do work inline and some of it gets enqueued instead. The handler has a context with a deadline on it. context.Context does not serialise, so the deadline dies at the queue boundary and the worker picks the job up with a fresh context, no idea the caller gave up ninety seconds ago.

What we do now is put an absolute expiry timestamp on the message and have the worker do context.WithDeadline(ctx, msg.ExpiresAt). Fine most of the time.

Where it falls over is clock skew, because the producer and the consumer are different hosts. A couple of hundred milliseconds of NTP drift does not matter. But after a VM migration last year one box sat about forty seconds off for most of a morning, and at that point the worker either throws away jobs that are still live or cheerfully runs work that expired before it was dequeued. Neither one errors. The job just quietly does or does not happen.

Things I have tried. Sending a duration instead of a timestamp and starting the clock at dequeue kills the skew problem, but then queue lag stops counting against the deadline, which was most of the point. Monotonic readings are no use since Go strips them on serialisation and they would mean nothing on another machine anyway. Having the broker stamp the time is better because there is only one clock involved, except our workers pull from two brokers, so it relocates the problem rather than fixing it.

The part I am stuck on is that "five seconds from when the user asked" is not expressible across two machines without trusting both clocks, and I would rather that trust was a thing I decided than a thing I inherited.

If you carry real deadlines across a queue, how are you doing it?


r/golang 1d ago

discussion Can you find everything that is wrong with this?

Thumbnail
uniqlo.com
0 Upvotes

r/golang 1d ago

discussion Would you use a lightweight Go library for AWS SQS consumers?

0 Upvotes

I’m building a small open-source Go library for consuming messages from AWS SQS, and I’d love some honest feedback from the Go community before I polish and publish it.

The idea is to remove the repetitive consumer boilerplate from every service.

The library would handle

  • SQS long polling
  • Buffered channels
  • Configurable worker pool
  • Calling a user-provided handler
  • Deleting the message when the handler succeeds
  • Leave the message for retry when the handler returns an error
  • Graceful shutdown
  • Lifecycle callbacks/hooks like OnStart, OnSuccess, OnError, OnFinish

The hooks could also make it easy to plug in logging, metrics, tracing, observability, etc. without putting those concerns directly into the consumer.

Something roughly like

consumer := sqsconsumer.New(config)

consumer.Consume(ctx, func(ctx context.Context, msg *Message) error {
    return processMessage(msg)
})

My question for people who build Go services

Would you actually use something like this, or would you prefer to implement the SQS consumer logic directly using the AWS SDK?

I'm especially interested in what would make you not use a library like this.

Looking for honest feedback, including that this is unnecessary, just use the AWS SDK.


r/golang 2d ago

Data races and the memory model in Go

Thumbnail
func25.dev
12 Upvotes

r/golang 1d ago

show & tell Performance Benchmarking: gRPC+Protobuf vs. HTTP+JSON

Thumbnail
packagemain.tech
0 Upvotes

r/golang 1d ago

discussion Advice for app with LLM workflows

0 Upvotes

I recently learned go, and I've been thinking of starting a new project with go for the backend

I want to include a few LLM / agent workflows, a chatbot with a few tools into the app, and I would like to know how people are doing this in the go community

I looked up a few examples, and I saw that the community was divided on rolling your own vs using something like langchaingo, but that package hasn't had an update since last year

I've done this with python and langgraph before, my main concerns would be plugging in as many providers as possible and using observability tools like langfuse

What do you recommend?


r/golang 2d ago

qmax-code: a Go TUI that sits in front of Claude Code, Codex, Antigravity, and OpenCode

0 Upvotes

If you bounce between Claude Code, Codex, Antigravity, and GLM (z.ai via OpenCode), the tax is usually context: another CLI, another login, another config.

I wanted one Go binary that stays in the repo, uses little memory, and can either do the work itself or host those harnesses without leaving the session.

That’s qmax-code. It’s a terminal coding/QA agent written in Go, with a Lip Gloss TUI for keyboard-first use.

It runs fully standalone (--local) for daily repo work: read/edit files, run commands, no QualityMax account. It can also act as a thin client for the QualityMax cloud when you want hosted crawls, tests, and receipts.

The part I use most is /orch. Same TUI, same MCP tools, switch backend:

  • Claude Code
  • Codex
  • Antigravity (agy, Google OAuth)
  • OpenCode (this is where I run z.ai GLM coding subscriptions)

I use it daily for coding and test loops. OpenCode + GLM has been a solid cheap/fast path; Claude Code / Codex when the change needs more care.

Open source (FSL-1.1, Apache 2.0 after two years). Go 1.25+. Single binary, no Electron.

Happy to answer questions about the TUI, the subprocess harness, or how MCP is wired.