Skip to content
View JoelTeoGom's full-sized avatar
♟️
Learning
♟️
Learning

Block or report JoelTeoGom

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
JoelTeoGom/README.md
Joel Teodoro

Backend Engineer · Go & Distributed Systems · Catalonia, Spain 🇪🇸


Typing SVG



Gmail     LinkedIn     Blog


$ whoami

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.


$ cat stack.yml

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

$ ps aux | grep focus

@@ 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 rush

$ tree ~/projects --favorites

Small systems, each built to understand one specific failure mode. All of them run.

go-sharded-ws-hub

Fan-out that survives slow clients

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 hash(eventID).

go-redis-token-bucket

One limit, N nodes, no drift

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.

go-priority-scheduler

Idle workers that actually sleep

Min-heap for ordering, sync.Cond for parking. Highest-priority job runs first and nobody burns a core spinning on an empty queue.

CrispLite

Chat, end to end

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.

DDD-Ecommerce

Aggregates that defend themselves

Real bounded contexts (Order, Catalog), invariants enforced inside the aggregate instead of in a service somewhere, domain events over a decoupled bus.

my-http-server

HTTP, parsed by hand

Request parsing, routing and responses written from scratch over raw TCP. The fastest way I know to stop treating net/http as magic.

./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

$ cat ~/writing/latest.md

Deep dives from runtimerants.dev. Long-form, with the benchmarks and the source, because "it's faster" isn't an argument:


$ curl -s runtimerants.dev/api/links

{
  "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"
}

$ git log --stat


// TODO: write better commit messages

Pinned Loading

  1. CrispLite CrispLite Public

    Real-time 1:1 chat in Go — WebSockets, Redis Pub/Sub, PostgreSQL. Built to learn how real-time messaging systems work under the hood.

    Go

  2. DDD-Ecommerce DDD-Ecommerce Public

    Designed and built an e-commerce backend applying Domain-Driven Design principles: bounded contexts (Order, Catalog), aggregates enforcing business invariants, domain events with a decoupled event …

    Go

  3. go-priority-scheduler go-priority-scheduler Public

    A minimal, runnable priority job scheduler in Go: a worker pool that runs the most-prioritary job first, built on a min-heap for ordering and sync.Cond to park idle workers without busy-looping.

    Go

  4. go-redis-token-bucket go-redis-token-bucket Public

    Distributed rate limiter in Go using a Redis-backed token bucket. An atomic Lua script enforces a shared limit across multiple nodes, demonstrating how single-threaded Redis guarantees correctness …

    Go

  5. realtime-odds-platform realtime-odds-platform Public

    A real WebSocket gateway in Go (Gorilla): a sharded in-memory hub that fan-outs event updates to subscribed clients, with per-connection write pump, non-blocking send (drop/close on slow consumers)…

    Go

  6. my-http-server my-http-server Public

    MyHTTPServer is a custom-built HTTP server written in Go, created as a learning project to understand how HTTP works under the hood. The goal of this project is to explore the core functionality of…

    Go