[{"data":1,"prerenderedAt":440},["ShallowReactive",2],{"navigation":3,"blog-page":22,"blogs":32},[4],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Blog","\u002Fblog","blog",[9,13,17],{"title":10,"path":11,"stem":12},"From Code to Cluster: My End-to-End Backend & AI Engineering Lifecycle","\u002Fblog\u002Ffrom-mockup-to-market","blog\u002Ffrom-mockup-to-market",{"title":14,"path":15,"stem":16},"The Mechanics of Latency in API Architecture","\u002Fblog\u002Fmechanics-of-latency-in-api-architecture","blog\u002Fmechanics-of-latency-in-api-architecture",{"title":18,"path":19,"stem":20},"The Case for Monolithic Core Logic in a Microservice-Hyped World","\u002Fblog\u002Fthe-case-for-modular-monolith","blog\u002Fthe-case-for-modular-monolith",false,{"id":23,"title":24,"body":25,"description":26,"extension":27,"links":25,"meta":28,"navigation":29,"path":6,"seo":30,"stem":7,"__hash__":31},"pages\u002Fblog.yml","Dev Log & Deep Dives",null,"Some of my recent thoughts on high-stakes backend architectures, proper agentic AI workflows, and scaling production infrastructure without the headache.","yml",{},true,{"title":24,"description":26},"hkTaN15sGt_U7U4CwUmdTN3NUjgwm0bT-P0Vs4Z6dmE",[33,314,371],{"id":34,"title":10,"author":35,"body":39,"date":306,"description":307,"extension":308,"image":309,"meta":310,"minRead":311,"navigation":29,"path":11,"seo":312,"stem":12,"__hash__":313},"blog\u002Fblog\u002Ffrom-mockup-to-market.md",{"name":36,"avatar":37},"Hugo Edmoundo",{"src":38,"alt":36},"https:\u002F\u002Fi.pinimg.com\u002F1200x\u002Fe5\u002F9b\u002F9e\u002Fe59b9e057f0ec9bdc2a88d7ae97efa3e.jpg",{"type":40,"value":41,"toc":282},"minimark",[42,46,49,54,57,62,70,74,85,89,92,105,109,112,116,119,123,126,154,158,161,187,191,194,198,201,205,208,211,222,226,229,233,236,251,255,258,262,265,276,279],[43,44,45],"p",{},"Building production software isn't just about writing code—it's about setting up a repeatable framework that handles complex logic without slowing down development. After tweaking my setup across a few production codebases, I’ve mapped out an end-to-end workflow that bridges heavy backend logic with modern, context-aware AI layers.",[43,47,48],{},"Here’s a breakdown of my engineering lifecycle, using the development of my AI-powered learning engine (Smart Study Room) as a direct case study.",[50,51,53],"h2",{"id":52},"phase-1-architecture-data-scoping","Phase 1: Architecture & Data Scoping",[43,55,56],{},"Before touching any endpoints, the absolute first priority is fixing the data structure. For this specific AI platform, the main challenge was handling massive amounts of unstructured, uploaded documents and structuring them for evaluations without blowing up the server's memory.",[58,59,61],"h3",{"id":60},"schema-modelling-typing","Schema Modelling & Typing",[43,63,64,65,69],{},"I started by mapping out a strictly typed data layer using ",[66,67,68],"code",{},"SQLModel",". Merging SQLAlchemy and Pydantic into a single workflow meant our data validation stayed solid all the way from the PostgreSQL storage layer up to the API routes. No messy data types, no runtime surprises.",[58,71,73],{"id":72},"monorepo-scaffolding","Monorepo Scaffolding",[43,75,76,77,80,81,84],{},"To keep things modular and clean, I isolated the core services within a unified monorepo managed by ",[66,78,79],{},"moonrepo",". It allowed me to separate the raw backend logic from the experimental AI engines, while using the ",[66,82,83],{},"uv"," package manager to handle dependency caching instantly. It saves a mental amount of setup time, to be fair.",[58,86,88],{"id":87},"setting-the-baselines","Setting the Baselines",[43,90,91],{},"We set a few non-negotiable performance thresholds before writing the actual router logic:",[93,94,95,99,102],"ul",{},[96,97,98],"li",{},"API endpoint round-trips must stay under 200ms.",[96,100,101],{},"The document parsing engine needs to ingest complex PDFs within 15 seconds.",[96,103,104],{},"Maintain persistent state tracking for multi-turn user agent conversations.",[50,106,108],{"id":107},"phase-2-backend-development-ai-integration","Phase 2: Backend Development & AI Integration",[43,110,111],{},"Once the data blueprints were locked in, I shifted focus to building out the core processing engines and wiring up the AI pipelines.",[58,113,115],{"id":114},"asynchronous-apis-with-fastapi","Asynchronous APIs with FastAPI",[43,117,118],{},"I used FastAPI for the application router, leveraging its native async support and out-of-the-box OpenAPI docs. The route architecture relies heavily on dependency injection patterns to keep database sessions cleanly isolated and secure per request.",[58,120,122],{"id":121},"designing-the-rag-pipeline","Designing the RAG Pipeline",[43,124,125],{},"To drive the smart study engine, I built a custom Retrieval-Augmented Generation (RAG) pipeline to parse and fetch document context:",[127,128,129,136,142,148],"ol",{},[96,130,131,135],{},[132,133,134],"strong",{},"Extraction Layer"," — Chunks and cleans raw text extracted from uploaded PDFs.",[96,137,138,141],{},[132,139,140],{},"Vector Space Mapping"," — Generates embeddings and maps them into a vector space for similarity ranking.",[96,143,144,147],{},[132,145,146],{},"Context Injection"," — Dynamically feeds the highest-ranked context straight into the LLM system prompt.",[96,149,150,153],{},[132,151,152],{},"Agent Orchestration"," — Runs an internal verification loop to ensure quizzes and evals are accurate without drifting out of the context window.",[58,155,157],{"id":156},"guardrails-i-stick-to","Guardrails I Stick To",[43,159,160],{},"To prevent the backend from choking under heavy concurrency, I followed a few strict design constraints:",[93,162,163,169,175,181],{},[96,164,165,168],{},[132,166,167],{},"Fail Fast:"," Pydantic layers enforce strict type-checking at runtime.",[96,170,171,174],{},[132,172,173],{},"Non-blocking IO:"," Offload all heavy document processing to asynchronous tasks.",[96,176,177,180],{},[132,178,179],{},"Stateless Routers:"," Keep the API workers stateless, delegating data tracking entirely to the database.",[96,182,183,186],{},[132,184,185],{},"Session Linking:"," Ensure every multi-turn agent conversation maps perfectly to a secure session ID.",[50,188,190],{"id":189},"phase-3-optimising-high-speed-api-delivery-for-premium-ui","Phase 3: Optimising High-Speed API Delivery for Premium UI",[43,192,193],{},"Once the backend engine was solid, the next step was making sure the client-side could actually render our data streams smoothly.",[58,195,197],{"id":196},"feeding-the-nextjs-ecosystem","Feeding the Next.js Ecosystem",[43,199,200],{},"Even though I focus heavily on backend architecture, I designed our API responses to integrate seamlessly with Next.js Server Components. The goal was simple: serve database context instantly so the presentation layer could handle the heavy rendering lift efficiently.",[58,202,204],{"id":203},"handling-the-liquid-glass-overhead","Handling the \"Liquid Glass\" Overhead",[43,206,207],{},"The frontend of this platform uses an ultra-modern, high-end \"Liquid Glass\" (glassmorphism) style with fluid parallax scroll effects. It looks incredible, but it can get proper laggy if the API delivery is slow.",[43,209,210],{},"By micro-optimising our FastAPI endpoints and implementing chunked streaming responses for the AI context, we managed to:",[93,212,213,216,219],{},[96,214,215],{},"Pass heavy data payloads to glassmorphic components with near-zero latency.",[96,217,218],{},"Keep the rendering smooth at a consistent 60fps on complex user dashboards.",[96,220,221],{},"Stream multi-turn evaluation text live, removing the annoying wait times for the user.",[50,223,225],{"id":224},"phase-4-dedicated-vps-infrastructure","Phase 4: Dedicated VPS Infrastructure",[43,227,228],{},"A system is only as good as the infrastructure running it. I skipped generic shared hosts—which are rubbish for running AI workflows—and went straight for a dedicated setup.",[58,230,232],{"id":231},"provisioning-the-server","Provisioning the Server",[43,234,235],{},"I configured a high-performance VPS instance over on Contabo to gain absolute performance control and harden our production environment:",[93,237,238,241,244],{},[96,239,240],{},"Locked down unauthorized port tunnels and configured root-access firewalls.",[96,242,243],{},"Set up an Nginx reverse proxy to route incoming web traffic efficiently.",[96,245,246,247,250],{},"Provisioned secure, auto-renewing SSL certs across our custom domains (",[66,248,249],{},"luminaprep.my.id",").",[58,252,254],{"id":253},"automated-cicd","Automated CI\u002FCD",[43,256,257],{},"I wired up a clean CI\u002FCD pipeline to run automated verification tests before updating the live production binaries. This completely removed manual deployment friction and dropped our live system downtime to absolute zero.",[50,259,261],{"id":260},"results-key-takeaways","Results & Key Takeaways",[43,263,264],{},"A few months after rolling this out to production, the metrics speak for themselves:",[93,266,267,270,273],{},[96,268,269],{},"Zero database race conditions during concurrent stress tests.",[96,271,272],{},"AI contextual responses maintained a solid 96% accuracy rate.",[96,274,275],{},"Server-side response latency dropped significantly thanks to proper async connection pooling.",[43,277,278],{},"The biggest takeaway? Always design your systems to be modular from day one. Because we decoupled the vector storage from our main relational database, updating our AI agents or tweaking the core API endpoints remains completely painless.",[43,280,281],{},"If you chaps are building local monorepos or messing around with agentic RAG workflows, I'd love to hear how you handle your setup. Let’s chat in the comments!",{"title":283,"searchDepth":284,"depth":284,"links":285},"",2,[286,292,297,301,305],{"id":52,"depth":284,"text":53,"children":287},[288,290,291],{"id":60,"depth":289,"text":61},3,{"id":72,"depth":289,"text":73},{"id":87,"depth":289,"text":88},{"id":107,"depth":284,"text":108,"children":293},[294,295,296],{"id":114,"depth":289,"text":115},{"id":121,"depth":289,"text":122},{"id":156,"depth":289,"text":157},{"id":189,"depth":284,"text":190,"children":298},[299,300],{"id":196,"depth":289,"text":197},{"id":203,"depth":289,"text":204},{"id":224,"depth":284,"text":225,"children":302},[303,304],{"id":231,"depth":289,"text":232},{"id":253,"depth":289,"text":254},{"id":260,"depth":284,"text":261},"2026-05-30","A practical breakdown of my software engineering workflow—from SQLModel schema design to provisioning root-access VPS environments for RAG systems.","md","https:\u002F\u002Fimages.pexels.com\u002Fphotos\u002F1050312\u002Fpexels-photo-1050312.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",{},8,{"title":10,"description":307},"Cf5wc1N4yRfKot8aQGw2JItAJsB-F0jG4-IcPT3SVLQ",{"id":315,"title":14,"author":316,"body":318,"date":364,"description":365,"extension":308,"image":366,"meta":367,"minRead":368,"navigation":29,"path":15,"seo":369,"stem":16,"__hash__":370},"blog\u002Fblog\u002Fmechanics-of-latency-in-api-architecture.md",{"name":36,"avatar":317},{"src":38,"alt":36},{"type":40,"value":319,"toc":362},[320,323,330,333,336,339,356,359],[43,321,322],{},"Latency optimisation is one of the most powerful vectors in my engineering toolkit, yet it is often completely ignored until a system proper struggles under heavy concurrency. After executing a series of load tests and benchmark simulations during the development of my corporate payroll engine, I gathered some absolutely mental data regarding how data layer architecture directly impacts runtime performance.",[43,324,325,326,329],{},"When we initially launched our automated computation worker, we relied on traditional synchronous loop patterns to iterate over large structural records. The logic was mathematically sound, but our batch-processing metrics were, honestly, pretty underwhelming. On a hunch, I proposed testing an asynchronous concurrent processing loop using Python's ",[66,327,328],{},"asyncio"," routines while keeping the raw computation logic identical.",[43,331,332],{},"The results were striking: switching to non-blocking database queries and batch-async execution reduced our compute overhead by a massive 34%. Even more interesting was how the storage layer responded to connection pool limits—highly optimised index configurations held steady under traffic spikes, whereas un-indexed tables bottlenecked processing memory regardless of how many threads we threw at them.",[43,334,335],{},"Beyond backend execution metrics, I discovered that structural UI feedback drastically affected user anxiety regarding waiting times. By implementing micro-optimised, streaming payload feedback in our loading views, users perceived the data sync to be much faster, even though the total round-trip processing duration at the server boundary stayed the same. It's all about managing the vibes alongside the data.",[43,337,338],{},"I've since developed a solid framework for profiling and mitigating performance lag that goes way beyond just throwing money at simple server hardware upgrades:",[127,340,341,344,347,350,353],{},[96,342,343],{},"Map out structural query bounds to pinpoint blocking IO bottlenecks",[96,345,346],{},"Profile connection pool scaling against realistic concurrent traffic spikes",[96,348,349],{},"Implement database indexing and proper clean caching headers on high-read endpoints",[96,351,352],{},"Offload long-running analytical operations into asynchronous background workers",[96,354,355],{},"Utilise streaming responses for data-heavy context generation (like RAG pipelines)",[43,357,358],{},"The most valuable lesson I've learned is that there is no universal \"magic setting\" for server hardware—that's complete rubbish. There are only architectures that effectively manage resource allocation and process data naturally within your specific software context.",[43,360,361],{},"Next time you are drafting an application router, look past simple logic completion and consider what your operational code is actually asking from your infrastructure, chaps.",{"title":283,"searchDepth":284,"depth":284,"links":363},[],"2026-03-15","Exploring how proper backend choices and data layer optimisations can slash system response times, manage concurrent overhead, and kill latency spikes.","https:\u002F\u002Fimages.pexels.com\u002Fphotos\u002F40799\u002Fpaper-colorful-color-loose-40799.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",{},5,{"title":14,"description":365},"6tOWRDJz2QWvLpg8l_7vCk_Ez7S3lOPfM86AJjXx_B8",{"id":372,"title":18,"author":373,"body":375,"date":433,"description":434,"extension":308,"image":435,"meta":436,"minRead":437,"navigation":29,"path":19,"seo":438,"stem":20,"__hash__":439},"blog\u002Fblog\u002Fthe-case-for-modular-monolith.md",{"name":36,"avatar":374},{"src":38,"alt":36},{"type":40,"value":376,"toc":431},[377,380,387,398,401,404,421,428],[43,378,379],{},"I recently took on a project that proper challenged everything about the industry's absolute obsession with distributed systems. A client wanted a complex data infrastructure, and conventional tech advice dictated spinning up an intricate maze of dozens of isolated microservices—which is, honestly, complete rubbish for most applications. It's the exact setup that introduces proper painful network lag, complex service discovery, and massive deployment overhead.",[43,381,382,383,386],{},"This got me thinking deeply about what I call the ",[132,384,385],{},"\"modular monolith\"","—an intentional, high-performance approach that keeps application code unified under a single robust core while strictly isolating internal domains.",[43,388,389,390,393,394,397],{},"For the production payroll engine at PT Pangestu Suryaning Famili, I experimented with this architecture. Instead of managing independent server nodes for payroll math, employee records, and reporting, I built a structured monolith leveraging ",[132,391,392],{},"Laravel's enterprise capabilities",". I engineered explicit domain boundaries and clean, highly optimised database relationships using ",[132,395,396],{},"MySQL",". The result? A system that shared data memory spaces instantly instead of making costly, low-key unnecessary HTTP round-trips between microservices.",[43,399,400],{},"Stress testing the unified infrastructure revealed something absolutely mental: the backend maintained 3x higher throughput with near-zero network latency compared to distributed API approaches. Furthermore, handling local debugging and code tracking within a single, well-structured framework became effortlessly simple. By engineering for simple cohesion rather than premature distribution, we achieved bulletproof execution speeds.",[43,402,403],{},"I've since developed a framework for profiling and preserving monolithic integrity that goes way beyond just throwing money at server hardware upgrades:",[127,405,406,409,412,415,418],{},[96,407,408],{},"Map out structural query bounds to pinpoint blocking database operations early",[96,410,411],{},"Profile connection pool scaling and MySQL indexing against realistic traffic spikes",[96,413,414],{},"Implement strict service boundaries within the framework to prevent tight, messy coupling",[96,416,417],{},"Offload heavy computational tasks (like automated payroll calculations) into background workers",[96,419,420],{},"Utilize clean caching headers and structured responses on high-read internal endpoints",[43,422,423,424],{},"I am now incorporating modular monolithic strategies into all my heavy software architectures, constantly asking myself: ",[425,426,427],"em",{},"\"Where can we group processes together? How can we leverage robust internal framework boundaries instead of adding loose network connections?\"",[43,429,430],{},"In the industry's rush to optimise for microservice trends, we have forgotten that sometimes the most scalable and maintainable digital experiences are the ones that keep data boundaries close, reducing operational complexity down to a single, hyper-optimised node. Cheers to that, mates!",{"title":283,"searchDepth":284,"depth":284,"links":432},[],"2026-01-28","Why architecting a proper unified core before splitting services leads to cleaner data boundaries, mental throughput, and less operational headache.","https:\u002F\u002Fimages.pexels.com\u002Fphotos\u002F4050314\u002Fpexels-photo-4050314.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",{},7,{"title":18,"description":434},"4O9_xEcYG6kdOXy7xQRNE2St809cZUBFLnWIY1-Df2U",1780417958110]