• Labs icon Lab
  • Core Tech
Labs

Guided: Optimizing Flask Applications with Caching and Middleware

In high-traffic web applications, performance bottlenecks can slow down response times and increase server load. This guided Code Lab will teach you how to optimize your Flask applications using caching and middleware. You'll integrate Flask-Caching to store and retrieve frequently accessed data, reducing redundant database queries and improving speed. Additionally, you'll implement middleware for logging and request monitoring, giving you deeper insights into your application's performance. Through hands-on tasks, you'll measure and analyze performance improvements, ensuring your optimizations are effective. By the end of this lab, you’ll have the skills to enhance the efficiency, scalability, and observability of your Flask applications—key techniques for handling real-world traffic demands.

Labs

Path Info

Level
Clock icon Beginner
Duration
Clock icon 40m
Published
Clock icon Apr 07, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Test the App and Identify Performance Issues

    Test the App and Identify Performance Issues

    Before you jump into optimizing your Flask app, you need to prove there's actually a problem. Performance issues can often feel obvious, but it's always better to measure than to assume.

    In this step, you'll act like a developer investigating a performance report. You're going to:

    • Test the app as it currently behaves.
    • Observe how long it takes to respond.
    • Establish a baseline you can compare against later.

    ✅ What You'll Do

    You'll approach this in two ways:

    1. Use a Bash script to send multiple requests and time each one.
    2. Use a Python script to do the same in a way that's easier to automate or extend later.

    Both approaches will help you identify a key issue. The app takes around 2 seconds to return each response - even when it's serving the same data again and again.

    This is where caching will come in, but not yet. First, you will see the problem. ## 🖥️ Run the Bash Script to Test Performance

    Now run the script you created to observe how your Flask app is performing. You’ll do this in two Terminal windows - one for running the app, and one for testing it.


    ✅ 1. Start the Flask App

    Open a Terminal window and navigate to your project directory. Then run:

    flask run
    

    You should see output like this:

     * Running on http://127.0.0.1:5000
    

    Keep this Terminal open - your app is now running and ready to receive requests.


    ✅ 2. Open a Second Terminal Window

    In the second Terminal, you’ll use your test script to simulate 5 requests to the app.


    ✅ 3. Make the Bash Script Executable

    Run the following:

    chmod +x test_baseline.sh
    

    This tells your operating system that the script is allowed to run as a program.


    ✅ 4. Run the Script

    Now execute the script:

    ./test_baseline.sh
    

    ✅ 5. Observe the Output

    You should see something like this:

    Testing response time for 5 consecutive requests to /quote
    
    Request 1:
    {"quote":"Keep it simple."}
    
    real    0m2.003s
    
    Request 2:
    {"quote":"Keep it simple."}
    
    real    0m2.001s
    
    ...
    

    Each request takes about 2 seconds, even when the result hasn’t changed.

    🧠 This is inefficient - and exactly the kind of problem caching is designed to fix. You will do that soon.

    ▶️ To Run your Script:

    Make sure your Flask app is running in another Terminal window, then in your second Terminal run:

    python3 test_baseline.py
    

    💡 What to Look For:

    You should see output like:

    Request 1: 2.01s - "Keep it simple."
    Request 2: 2.00s - "Keep it simple."
    ...
    

    Each request takes about 2 seconds — even when it returns the same result. This confirms your app is doing unnecessary work and sets the stage for your optimization in the next step.

  2. Challenge

    Add `Flask-Caching` to Improve Performance

    Add Flask-Caching to Improve Performance

    🧠 Why This Matters

    In Step 1, you saw that your app takes about 2 seconds to respond to every request, even when it’s returning the same data. That’s unnecessary and inefficient.

    In the next task, you’ll fix that using Flask-Caching.

    Caching lets your app remember the result of expensive operations (like slow database queries or repeated API calls) and reuse them instead of recalculating every time. This can dramatically improve performance, especially for endpoints that don't change frequently.


    ✅ What You'll Do

    You're going to:

    • Install and configure Flask-Caching.
    • Apply it to the /quote endpoint.
    • Confirm that repeated requests are now much faster.

    The goal is to serve the same data instantly if it hasn't changed. This saves time, resources, and server load.

    This is one of the easiest and most effective performance wins you can implement in any web application. The first thing you need to do is install Flask-Caching, a popular extension that adds simple, flexible caching to your Flask app.

    Although this lab environment doesn’t have internet access, the package is already pre-installed — so running the install command will still work and confirm that the requirements are satisfied.

    ▶️ Run This Command in Your Terminal:

    pip install Flask-Caching
    

    You should see output similar to:

    Requirement already satisfied: Flask-Caching in /home/ps-user/.local/lib/python3.10/site-packages (2.3.1)
    

    That means you're ready to move on! ✅ ### ✅ What This Does

    • The first time someone requests /quote, the function runs normally and takes about 2 seconds.
    • The result is then cached in memory.
    • If another request comes in within 10 seconds, Flask will skip running the function and return the cached result instantly.

    You've just made your first performance optimization - great job!

    Set a Short Expiration and Test That Cache Expires

    So far, your /quote endpoint is cached using the default timeout of 10 seconds. But what if you want more control?

    In this step, you’ll:

    • Add a second endpoint with its own caching rule.
    • Set a shorter cache timeout so you can test cache expiry in action.

    This helps you understand how and when cached responses expire, which is especially important for endpoints that return frequently changing data.

    ▶ How to Test It

    1. Restart your Flask app:

      flask run
      
    2. In another Terminal, make 3 requests spaced apart like this:

      curl http://127.0.0.1:5000/quote-short-cache  # slow (first request)
      curl http://127.0.0.1:5000/quote-short-cache  # fast (cached)
      curl http://127.0.0.1:5000/quote-short-cache  # slow again (cache expired)
      

    ✅ What You Should See

    • The first request takes about 2 seconds.

    • The second request is almost instant and returns the same quote.

    • The third request (after 4 seconds) is slow again and may return a different quote - showing that the cache expired and was refreshed.


    🧠 Why This Matters

    • Caching improves performance, but you also need to keep your data fresh.
    • Setting different expiration times per endpoint gives you full control.

    You don't always want to cache forever. Sometimes, you just want a few seconds of speed.


    You're now in full control of caching behavior. In the next step, you'll shift gears and focus on logging and monitoring performance - so you can see what your app is actually doing behind the scenes.

  3. Challenge

    Add Logging Middleware

    Add Logging Middleware

    🧠 Why This Matters

    Now that your app is faster, it's time to make it observable. Performance improvements are great but in a real-world app, you need visibility into what's happening under the hood.

    In this next task, you'll add middleware that logs basic request information every time someone hits your API. This is a common and essential step in any production-ready application.

    If something goes wrong, logs are often the first and best place to start investigating.


    ✅ What You'll Do

    You're going to:

    • Create a middleware function that logs each request.
    • Use Flask's before_request and after_request hooks.
    • Write basic request information to a log file.

    The goal is to capture useful details like:

    • The HTTP method (GET, POST, etc.)
    • The path of the request (e.g. /quote)
    • The response status code (e.g. 200)
    • A timestamp showing when the request occurred

    Logging helps you monitor usage, debug issues, and understand how your app is being used.

    Ready? Start building your first middleware function.

  4. Challenge

    Flag and Monitor Slow Requests

    Flag and Monitor Slow Requests

    🧠 Why This Matters

    Now that your app logs every request, it's time to make those logs more meaningful by identifying which requests are taking too long.

    In this next task, you'll enhance your middleware to:

    • Measure how long each request takes.
    • Flag any request that takes longer than 1 second.
    • Log slow requests to a separate file for easier monitoring.

    This is a common technique in production environments where you want to catch performance issues before users start reporting them.

    Logging is useful. Smart logging is powerful.


    What You'll Do

    You'll update your existing logging middleware to:

    • Calculate how long each request takes (from start to finish).
    • Add a warning flag (⚠️ SLOW) to any request that takes longer than a defined threshold.
    • Write slow requests to a dedicated file called slow_requests.log.

    This gives you better visibility into which parts of your app need optimization and when they need it.

    Now you will make your logs smarter. Now that you've completed this step, your app will automatically track slow requests and give you a clear signal when something is taking longer than it should.

    In the next step, you'll test this and confirm that the logs reflect your changes.

  5. Challenge

    Validate Your Optimisations

    Validate Your Optimizations

    🧠 Why This Matters

    You've made meaningful improvements to your Flask app, but how do you know it worked?

    In this final step, you'll rerun the baseline scripts from the very first task to confirm that your changes had a real impact. You'll see requests go from slow and repetitive to fast and efficient and you'll be able to trace it all in your logs.


    ✅ What to Do

    1. Make sure your Flask app is running:

      flask run
      
    2. Open the second Terminal and rerun the scripts you used in Task 1:

      • Bash version:

        ./test_baseline.sh
        
      • Python version:

        python3 test_baseline.py
        

    What You Should See

    • The first request still takes about 2 seconds because it isn't cached yet.
    • The following requests are nearly instant.
    • In request.log, you'll see:
      • The first request marked "⚠️ SLOW".
      • Subsequent requests do not have the slow flag.
    • In slow_requests.log, only the first request should be recorded.

    This confirms that:

    • The caching is working.
    • Slow requests are being monitored.
    • Your logs are capturing meaningful insight about how your app performs.

    🎉 Conclusion

    You've now completed a full performance pass on your Flask app!
    Here’s what you accomplished:

    ✅ Identified and confirmed a performance issue
    ✅ Integrated Flask-Caching to optimize repeated responses
    ✅ Added middleware to log and monitor real requests
    ✅ Flagged and isolated slow requests for performance visibility
    ✅ Validated the impact of your changes with real-world testing

    These are exactly the kinds of practices developers use in production environments — small, measurable steps that make software faster, safer, and easier to maintain.

    👏 Well done! You've not only improved your app, you've made it observable and scalable.

Kevin is a Developer Educator, speaker and writer based in beautiful Northern Ireland. He specializes in web development across a range of languages and frameworks.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.