1Stop

Welcome to your one-stop destination for all things tech! Insightful blogs, code snippets, and industry updates for developers of all levels — from Java and Spring Boot to Docker, Kafka, and AWS.

After the Outbox: The Saga Pattern for Multi-Service Transactions in Spring Boot

It’s 3 AM again. A customer placed an order, payment went through, and inventory reservation failed — the warehouse is out of stock. The customer has been charged for something that will never ship. The order row exists and the customer was charged, but nothing will ship — and no single transaction can unwind it, because there is no @Transactional that spans your order service, your payment service, and your inventory service. Each one already committed its own local transaction. ...

2026-09-29 · 11 min · Ramesh

Spring Boot 4.1's First-Class gRPC: Server + Client in One Project

Adding gRPC to Spring Boot traditionally meant choosing a third-party starter such as LogNet or yidongnan, managing gRPC versions, and dealing with server configuration yourself. Spring gRPC 1.0 made it official but kept the auto-configuration outside Boot. Spring Boot 4.1 finished the job: the auto-configuration moved into Boot itself, the starters are on start.spring.io, and the BOM manages the versions of the gRPC dependencies it provides. If you’re comfortable building REST endpoints with Spring, Spring Boot 4.1 makes the gRPC programming model feel surprisingly familiar. ...

2026-09-28 · 6 min · Ramesh

Dual Writes Are Lies: The Transactional Outbox Pattern in Spring Boot + Kafka

It’s 3 AM. A customer paid, the orders row is in your database, and the OrderCreated event never reached Kafka. The warehouse never shipped. The email never sent. Somewhere in your service there is code that looks like this: @Transactional public Order placeOrder(PlaceOrder cmd) { Order order = orderRepository.save(new Order(cmd)); // write #1 kafkaTemplate.send("orders", order.getId(), toJson(order)); // write #2 — outside the safety net return order; } Two writes. No shared atomicity. If the broker is down, if the pod gets killed, if the send times out after the commit — the database and the downstream world silently disagree, and you get to find out from an angry customer. This is the dual-write problem, and the fix is the transactional outbox pattern. ...

2026-09-27 · 7 min · Ramesh

Replace YNAB: Self-Host Actual Budget in One Docker Container

YNAB is $14.99 a month — $180 a year — for envelope budgeting. That’s a subscription to be told where your own money went. Actual Budget is the open-source clone: same “give every dollar a job” philosophy, local-first so it works offline, and a tiny server that syncs your budget between devices. One container, zero dollars, your data never leaves your network. The math YNAB Actual Budget (self-hosted) Cost $14.99/mo ($180/yr) $0 Budgeting method Envelope Envelope Your data lives YNAB’s cloud Your /data folder Works offline Mostly Yes — local-first Bank sync Built-in, polished US/EU only (see below) Mobile apps Yes Yes (point at your server) The honest trade-off is bank sync — more on that below. Everything else is at parity or better. ...

2026-09-26 · 4 min · Ramesh

Exactly-Once POSTs: Idempotency Keys in Spring Boot (Stripe-Style)

The client times out waiting for your POST /orders. It retries. Your server processes it twice. The customer gets charged twice, and your support queue gets a new entry titled in all caps. Stripe solved this a decade ago with one header: Idempotency-Key. The client generates a UUID, sends it with the request, and retries with the same key — Stripe guarantees one effect per key. It’s the industry reference implementation (docs, engineering blog), and there’s no reason your API can’t offer the same contract. Let’s build it. ...

2026-09-25 · 7 min · Ramesh