package main
import "fmt"
type Engineer struct {
Name string
Role string
Location string
Primary string
Focus []string
}
func (e Engineer) String() string {
return fmt.Sprintf("%s — %s, shipping %s to production", e.Name, e.Role, e.Primary)
}
func main() {
me := Engineer{
Name: "Joel Teodoro",
Role: "Backend Engineer",
Location: "Catalonia, Spain",
Primary: "Go",
Focus: []string{
"System design and the trade-offs nobody writes down",
"Concurrency: goroutines, channels, sync primitives",
"Real-time delivery: WebSocket fan-out, pub/sub, sharding",
"Data layer internals: B+ trees, WAL, replication, CDC",
},
}
fmt.Println(me)
// Joel Teodoro — Backend Engineer, shipping Go to production
}I work on booking platforms — hotels and buses. Payments, cancellations, refunds, and third-party APIs that document one thing and return another. Go on Kubernetes, real traffic, real money.
Most of what I know came from something breaking first. I write it down at runtimerants.dev so I don't have to learn it twice.
core:
language: go # everything I ship
apis: [graphql, grpc, rest, websockets]
data: [mysql, postgresql, redis, elasticsearch]
messaging: [pub/sub, rabbitmq, kafka]
infrastructure:
orchestration: [kubernetes, docker]
cloud: [gcp, cloud-run]
ci_cd: [gitlab-ci, github-actions]
architecture:
- hexagonal / ports & adapters
- domain-driven design
- event-driven services
- caching, and the harder half: invalidation
also_shipped:
- java / spring-boot # two years of it, same team. I wrote a post about it
- python, c # tooling and systems coursework@@ right now @@
+ System design — ride-hailing, ticketing, real-time feeds. Designed properly,
+ not four boxes and an arrow labelled "queue"
+ Cassandra internals — LSM trees, partition keys, and the hot partition problem
+ that every tutorial forgets to mention
+ Redis past the cache — atomic Lua, pub/sub internals, distributed coordination
+ RabbitMQ ingest — sharded consumers, backpressure, delivery guarantees that hold
@@ reading @@
+ Concurrency in Go — Cox-Buday. Finished it, then read it again
+ Designing Data-Intensive Applications — Kleppmann. Halfway, no rushSmall systems, each built to understand one specific failure mode. All of them run.
Sharded in-memory hub, one write pump per connection, non-blocking send. If a client
can't keep up it gets dropped — one slow consumer should never stall the broadcast.
Lock contention split across shards by |
Token bucket in Redis, enforced by an atomic Lua script. Redis being single-threaded isn't a limitation here — it's the entire correctness guarantee. |
Min-heap for ordering, |
WebSockets, Redis Pub/Sub for cross-instance delivery, Postgres for durability, hexagonal all the way down. Built it to find out what breaks in a messaging system. Plenty does. |
Real bounded contexts (Order, Catalog), invariants enforced inside the aggregate instead of in a service somewhere, domain events over a decoupled bus. |
Request parsing, routing and responses written from scratch over raw TCP. The fastest
way I know to stop treating |
./lab — concurrency patterns, isolated and runnable
| Repo | What it does |
|---|---|
go-errgroup-example |
Parallel fetch, ordered results, bounded concurrency, first error wins |
go-circuit-breaker-example |
The full CLOSED → OPEN → HALF-OPEN cycle against a downstream that keeps failing |
go-fanout-race |
Fan out N requests, keep the fastest, cancel the rest |
SingleFlight-Golang |
Collapsing duplicate in-flight calls so a cache miss doesn't become a stampede |
Snowflake-generator-service |
64-bit time-ordered IDs. Thread-safe, no collisions, no coordination |
Data-structures |
The usual suspects, from scratch, with generics |
Deep dives from runtimerants.dev. Long-form, with the benchmarks and the source, because "it's faster" isn't an argument:
- The
contextPackage — cancellation across a concurrent call graph, from done channels up - singleflight Internals — one hot key expires, N requests hit the DB. Here's how it collapses them
- Write-Ahead Log Internals — what actually happens on INSERT, and how it ends up as CDC
- DB Indexes & Transactions — B+ trees and row locks are the same story told twice
- Go vs Spring Boot — two years with both, same team, same infra, actual numbers
{
"blog": "https://runtimerants.dev",
"linkedin": "linkedin.com/in/joel-teodoro-gomez",
"email": "joel.teodoro.software@gmail.com",
"status": "open to backend / distributed systems roles — remote or Barcelona"
}
// TODO: write better commit messages