Yesterday I talked about what a broken bug pipeline looks like. Today, here's exactly how I built the fix. And the one database decision that made it 40% faster. 🧵 The goal was simple: Build a system where clients raise bugs, developers fix them, and everyone has exactly the information they need, nothing more, nothing less. That last part is the hard part. Decision 1 - Role-Based Access Control (RBAC) I split the system into two worlds: Client view → raise tickets, track status, add comments Developer view → claim bugs, update progress, resolve tickets Neither can touch what the other owns. Every endpoint is locked behind Spring Security + JWT validation. If you're not authenticated with the right role, you're not getting in. Decision 2 - The database problem nobody talks about Early versions of the system were slow. A single bug record needed: → Bug details → Assigned developer → Client who raised it → All comments Each one was a separate query. 10 bugs on a page = 40+ database hits. This is the N+1 query problem. It's silent, it's common, and it kills performance at scale. The fix: Many-to-one relational mapping in MySQL. Instead of fetching each relationship separately, I restructured the schema so JPA/Hibernate resolves everything in a single optimised JOIN. Result → query response time dropped from ~500ms to ~300ms. That's a 40% reduction. On every single page load. Decision 3 - Docker for deployment I containerised the entire stack. Frontend. Backend. Database. One command. Runs identically everywhere. No "works on my machine" conversations. No environment mismatches between dev and production. What I learned building this: Performance isn't a feature you add at the end. Security isn't a layer you bolt on after launch. Both need to be designed in from line one. The full project end-to-end breakdown is coming in Post 3. I'll show the complete architecture, the tech stack, and what I'd do differently. Follow along 🔔 #Java #SpringBoot #MySQL #Docker #SystemDesign #BackendDevelopment #BuildInPublic #SDE2026 #DatabaseOptimization #SpringSecurity
Building a Scalable Bug Pipeline with RBAC and Database Optimization
More Relevant Posts
-
🚨 𝗧𝘄𝗼 𝗳𝗮𝗶𝗹𝘂𝗿𝗲𝘀 𝗵𝗮𝗽𝗽𝗲𝗻𝗲𝗱. 𝗬𝗼𝘂𝗿 𝗹𝗼𝗴 𝘀𝗵𝗼𝘄𝘀 𝗼𝗻𝗲. Most developers know that try-with-resources closes resources automatically. But many miss this: ⚠️ if the try block fails, and then close() fails too, the close() exception becomes suppressed. And sometimes that second exception is exactly what tells you whether the output can still be trusted. Example 👇 try ( OutputStream out = Files.newOutputStream(path); ZipOutputStream zip = new ZipOutputStream(out) ) { writeEntries(zip); } Now imagine this actually happened: 📌 Primary exception writeEntries(zip) failed 📌 Suppressed exception zip.close() failed At first glance, you may think: ▪ one record failed ▪ export failed ▪ investigate the business/data issue But that is only half the story. Because for resources like ZipOutputStream, close() is not just cleanup. It may still need to: ▪ finish the ZIP structure ▪ flush remaining bytes ▪ write the final directory/footer So the suppressed exception can tell you something critical: 🚫 the output file may be incomplete or corrupted That changes the conclusion. Without the suppressed exception, you may think: ✅ "The export failed because of one bad record." With the suppressed exception, the better conclusion is: ❌ "The ZIP itself may be invalid. Do not trust the file." And here is how teams often hide that second failure: log.error("Export failed: {}", e.getMessage()); Now the log shows only the primary exception. The suppressed one is still there... but easy to miss. You need this: log.error("Export failed", e); And when needed, inspect: e.getSuppressed() 🧠 𝗧𝗵𝗲 𝗿𝗲𝗮𝗹 𝗹𝗲𝘀𝘀𝗼𝗻: The primary exception tells you why the operation failed. The suppressed exception may tell you whether the output can still be trusted. That is a huge difference in production. Especially for: 📦 ZIP / GZIP export 📄 CSV generation 💾 file writing 🌐 response/output streams ☁️ upload streams Miss the suppressed exception - miss half the story. Have you ever found the real operational clue inside getSuppressed()? 🤔 #Java #Backend #Exceptions #JavaIO #SoftwareEngineering #Debugging #CleanCode
To view or add a comment, sign in
-
-
Timeouts (The Small Setting That Saves Your System) --- Built:- A service calling multiple downstream APIs to fetch and aggregate data. --- Problem I faced:- Everything worked fine… until one dependency slowed down. Then suddenly: Requests started hanging Thread pool got exhausted API response time shot up Entire service became slow All because one service was taking too long. --- How I fixed it:- The issue was missing timeouts. Requests were waiting indefinitely. Fixes applied: Added strict timeouts for all external calls Used fallback responses where possible Combined with circuit breaker for failing services Monitored slow calls with proper logging Now: Slow services don’t block everything System fails fast instead of hanging Overall stability improved --- What I learned A slow dependency is sometimes worse than a failed one. At least failures are quick. Slow calls quietly kill your system. --- Question:- Do your API calls have proper timeouts… or are they waiting forever without you noticing? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment #RDBMS #PostgreSQL #backend
To view or add a comment, sign in
-
Ever spent hours chasing down a performance issue in your Spring application, only to realize it’s the classic N+1 problem? For anyone who hasn’t encountered it yet, it typically appears when you fetch a list of entities, and then Hibernate executes an additional query for each related entity. Instead of a single efficient query, you end up with N+1 queries hitting your database.Everything may look fine in development, but under real traffic, the impact becomes obvious. I recently ran into this with a simple parent-child relationship. The code looked clean and straightforward, but once I enabled SQL logging, it became clear that multiple unnecessary queries were being executed behind the scenes. What helped me address it:1- Enabling SQL logs to see what was really happening.2- Using JOIN FETCH in JPQL where appropriate3- Applying @EntityGraph for better control over fetching.4- Being more intentional about lazy versus eager loading. The main takeaway for me was that ORMs simplify development, but they don’t remove the need to understand how queries are executed. #Spring #Springboot #JPA #ORM #Database
To view or add a comment, sign in
-
-
Sometimes your system isn’t slow because of heavy logic. It’s slow because it’s waiting. Waiting for: another service a database an external API And while it waits, threads just sit there doing nothing. --- This is where Async Processing helps The idea is simple: Don’t block. Do the work later. --- What this looks like Instead of doing everything in one request: User places an order System saves order immediately Email is sent later Notification is processed in background The user doesn’t wait for everything. --- How it’s usually done Background jobs Message queues (Kafka, RabbitMQ) @Async in Spring Boot You move non-critical work out of the main flow. --- Why this matters Without async: Requests take longer Threads stay blocked System struggles under load With async: Faster response times Better scalability Smoother user experience --- Real-world example When you upload a file: You don’t wait for processing You get a response quickly Processing happens in background --- Trade-offs Async adds complexity: Harder to debug Requires retry handling Failures are not immediate --- Simple takeaway Not everything needs to happen right now. --- If your system is slow, how much of that work actually needs to be done synchronously? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment #RDBMS #PostgreSQL #backend
To view or add a comment, sign in
-
The Spring Boot annotation that is silently corrupting your database. If you are a Spring Boot developer, you probably use @Transactional every day. If something fails, the database rolls back. Simple, right? But what happens when you write code like this? @Service public class UserService { // The entry point called by the Controller public void registerUser(UserDTO dto) { // ... some validation logic ... saveUserAndSendEmail(dto); } @Transactional public void saveUserAndSendEmail(UserDTO dto) { userRepository.save(new User(dto.email())); emailService.sendWelcomeEmail(dto.email()); // What if this throws an exception? } } What you think happens: If the email service fails and throws an exception, @Transactional catches it, rolls back the database insert, and the user is not saved. What ACTUALLY happens: The database commits the user anyway. Your system now has a user who never got their welcome email, and your database is in an inconsistent state. Why did it fail? The "Proxy Bypass" Trap. Spring’s @Transactional doesn't work by magic; it works by creating an AOP Proxy around your class. When an outside class (like your Controller) calls your Service, it hits the Proxy first, which opens the database transaction. BUT... if you call a method from within the same class (like registerUser calling saveUserAndSendEmail), you are using the internal this reference. You completely bypassed the Spring Proxy. The transaction never started. The rollback will never happen. The Senior Fixes: 1. The Architecture Fix: Move the @Transactional logic to a separate UserRegistrationService. Calling an external class forces you to go through the proxy. 2. The Simple Fix: Put @Transactional on the entry-point method (registerUser) instead of the internal helper method. Stop assuming annotations are magic. If you don't understand how proxies work under the hood, your data is at risk! Have you ever spent hours debugging a @Transactional rollback that just wouldn't trigger? 👇 #Java #SpringBoot #Hibernate #BackendDevelopment #Microservices #SoftwareEngineering #CleanCode #TechTips #LogicLedaMagic
To view or add a comment, sign in
-
Dead Letter Queue (When Messages Keep Failing Silently) --- Built:- A background system processing messages from a queue (orders, emails, events). --- Problem I faced:- Everything worked fine… until some messages started failing. Then: Same message kept retrying Logs kept growing Queue got slower Some messages were never processed successfully Worse part? Failures were getting buried in retries. --- What was really happening:- Messages were failing repeatedly with no exit path. Every retry pushed them back into the queue. They kept coming back… again and again. --System was stuck in a loop. --- How I fixed it:- Introduced a Dead Letter Queue (DLQ). Instead of retrying forever: Set a max retry limit After limit → move message to DLQ Logged and monitored failed messages Added manual or automated reprocessing Now: Queue stays clean Failures are isolated No infinite retry loops --- What I learned:- Not every message should be retried forever. Some failures need attention — not repetition. --- Simple mental model:- Think of DLQ like a “quarantine zone”. Healthy messages → processed normally Problematic messages → isolated for inspection --- Carousel Breakdown:- Slide 1 → Messages failing repeatedly Slide 2 → Infinite retries Slide 3 → Queue slowdown Slide 4 → Introduce DLQ Slide 5 → Move failed messages Slide 6 → Inspect & reprocess --- Question In your system, what happens to messages that keep failing… do they stop somewhere, or retry forever? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment #RDBMS #PostgreSQL #backend
To view or add a comment, sign in
-
Partial Failure (When Only Part of Your System Breaks) --- Built:- A service that aggregates data from multiple services: User service Order service Recommendation service All combined into one response. --- Problem I faced:- Everything worked fine… until one dependency started failing. Then: Entire API failed Even though other services were working Users saw errors for everything One small failure took down the whole response. --- What was really happening:- This was a partial failure. Only one service failed… but the system treated it like a full failure. * No isolation * No fallback * No graceful handling --- How I fixed it:- Instead of failing everything: Added fallback responses for optional services Marked some data as non-critical Used timeouts + circuit breakers Returned partial responses where possible Now: Core data always loads Optional features degrade gracefully System stays usable even during failures --- What I learned:- In distributed systems, failure is normal. The goal is not to avoid failure. It’s to limit its impact. --- Simple mental model:- If one feature breaks, the whole app shouldn’t feel broken. --- Carousel Breakdown :- Slide 1 → One service fails Slide 2 → Entire API fails Slide 3 → Identify partial failure Slide 4 → Add fallbacks Slide 5 → Return partial response Slide 6 → System stays usable --- Question::- If one dependency in your system goes down, does your API fail completely… or degrade gracefully? #Java #SpringBoot #Programming #SoftwareDevelopment #Cloud #AI #Coding #Learning #Tech #Technology #WebDevelopment #Microservices #API #Database #SpringFramework #Hibernate #MySQL #BackendDevelopment #CareerGrowth #ProfessionalDevelopment #RDBMS #PostgreSQL #backend
To view or add a comment, sign in
-
Day 13. If you're returning Entities from your API, you're leaking your database. I made this mistake early: @GetMapping("/users/{id}") public User getUser(@PathVariable Long id) { return userRepository.findById(id).orElseThrow(); } Looks clean. But it's a security risk. Here’s what you might be exposing without realizing: → passwordHash → roles → internal flags like isAdmin That's not an API. That's your database leaking through JSON. And you probably didn't even notice it. The fix is simple: Return a DTO. @GetMapping("/users/{id}") public UserDTO getUser(@PathVariable Long id) { User user = userRepository.findById(id).orElseThrow(); return new UserDTO(user.getId(), user.getName(), user.getEmail()); } What you actually gain: → Security — control what leaves your server → Stability — DB changes don’t break your API → Clarity — frontend gets exactly what it needs The rule I follow now: → Entities belong to your database → DTOs belong to the outside world → Never mix the two Returning Entities is easy. Designing contracts is what makes you a backend developer. Are you still exposing entities directly? 👇 Drop it below #SpringBoot #Java #BackendDevelopment #DTO #JavaDeveloper
To view or add a comment, sign in
-
Over the past few days, I worked on designing and documenting a complete Spring Security implementation using JWT (JSON Web Tokens) for stateless authentication. This wasn’t just a demo — it’s structured like a real-world, scalable backend system. 💡 Key Highlights: ✔️ Stateless authentication using JWT ✔️ Secure password handling with BCrypt (strength 12) ✔️ Role-based authorization (ROLE_USER / ROLE_ADMIN) ✔️ Custom security filter with OncePerRequestFilter ✔️ Clean layered architecture (Controller → Service → Repository) ✔️ Database versioning using Flyway ✔️ Lightweight data access using JdbcTemplate (no JPA) 🔐 Security Flow Simplified: Every request passes through a custom JWT filter → token validation → user authentication → role-based authorization via Spring Security. ⚙️ Tech Stack: Spring Boot 4 Spring Security 6+ JWT (JJWT) Flyway Migration MySQL Lombok JdbcTemplate 📌 What I Focused On: Writing clean, maintainable security configuration Avoiding common pitfalls (CSRF misuse, hardcoded secrets, session state) Designing for real-world production readiness 📊 Why this matters: In modern microservices architecture, stateless security with JWT is critical for scalability, performance, and decoupled services. 💬 I’m currently exploring deeper into Spring ecosystem, system design, and cloud-native architectures. If you're working on similar implementations or have insights, let’s connect and discuss! #SpringBoot #SpringSecurity #JWT #Java #BackendDevelopment #Microservices #SystemDesign #SoftwareEngineering #TechLeadership #Flyway #Security #HappyLearning
To view or add a comment, sign in
-
🚀 N+1 Problem in Spring Boot 🔍 What is it? 1 query loads parent data + N queries load related data = N+1 queries 🚨 Impact on performance • Slower APIs • Heavy database load • Poor scalability ✔️ How to fix it? • JOIN FETCH → load everything in one query • @EntityGraph → clean , declarative solution • Batch fetching → reduce query count 💡 Optimizing your queries early can dramatically boost performance in production 🚀 #SpringBoot #Hibernate #Performance
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development