Problems from backend and infrastructure work, and the fixes that held up.

An engineering notebook by Valerio Mario Casale. Each entry starts with the problem, then the fix that worked and the reasoning behind it. It covers Kubernetes, the JVM, Python services, observability and local AI tooling.

9 entries: 5 notes and 4 essays. Last entry July 20, 2026.

entries

Newest first. The ring beside each entry shows how far you have read it on this device. Search all 9 in the archive

  1. Native image vs JVM on Spring Boot 4.1: 4.3x less memory, 18x faster startup Most native image vs JVM numbers come from benchmarks of other applications. Here one service is built both ways from the same source code and measured on the same dashboard, so the numbers describe this code on this cluster.
  2. Java, Python, Node and Rust on the same REST service: 7 MB to 191 MB at idle Moving a service to another language was expensive because of the integration work. The language itself was easy to learn. You had to choose a framework, an ORM, migrations and metrics, make them work together and connect them to the production tooling. AI coding tools now do much of that work, so the runtime choice is worth measuring again.
  3. InvestigatorAI: a multi-agent investigation system with LangChain4j, Neo4j and Qdrant An investigation question can need a graph query, a document search and a check of the sources. One model call cannot do all of this well. When the work is split into separate tasks, each one using real data, the answers are more accurate and you can see which step produced a wrong finding.
  4. Remote debugging a Spring Boot service on Kubernetes with JDWP When a bug appears only inside the cluster, debugging with logs means adding a log line, rebuilding the image, redeploying and reproducing the bug again. Each attempt takes minutes, and the new log line may still not show the value you need.
  5. One trace ID across Spring Boot, FastAPI and LangChain on Kubernetes with OpenTelemetry and Grafana When a service that calls two other services fails, you have to read three log streams and match the lines by timestamp. With one correlation ID in every request and every log line, one query returns all the lines of the failed request.
  6. Centralized exception handling in REST APIs with Spring and FastAPI An API often handles exceptions in one of two bad ways. It catches them and logs nothing, so nobody can find the error later. Or it lets them reach the client, and the response shows class names, table names and SQL.
  7. Local Kubernetes on a Mac: Minikube profiles, kubectl contexts and k9s Testing a change on a remote Kubernetes cluster means building an image, pushing it to a registry, deploying it and waiting, which takes minutes for every change. A local cluster removes the remote deploy from that loop.
  8. Java, Python and Node versions on a Mac with SDKMAN, pyenv and nvm Different projects need different Java, Python and Node versions. Without a version manager you have one version per language, and you reinstall runtimes by hand every time you change project.

reading paths

Some entries build on each other. A path puts them in order.

apps

Two applications I build and use, each with its own page.