[Python] Low RPS when perfomance testings django website

Discussão em 'Python' iniciado por Stack, Maio 26, 2025.

  1. Stack

    Stack Membro Participativo

    I have a code like this that caches a page for 60 minutes:

    import os
    import time
    from django.conf import settings
    from django.core.cache import cache
    from django.core.mail import send_mail
    from django.contrib import messages
    from django.http import FileResponse, Http404, HttpResponse
    from django.shortcuts import render
    from django.utils.translation import get_language, gettext as _

    from apps.newProduct.models import Product, Variants, Category
    from apps.vendor.models import UserWishList, Vendor
    from apps.ordering.models import ShopCart
    from apps.blog.models import Post
    from apps.cart.cart import Cart

    # Cache timeout for common data
    CACHE_TIMEOUT_COMMON = 900 # 15 minutes

    def cache_anonymous_page(timeout=CACHE_TIMEOUT_COMMON):
    from functools import wraps
    from django.utils.cache import _generate_cache_header_key

    def decorator(view):
    @wraps(view)
    def wrapper(request, *args, **kw):
    if request.user.is_authenticated:
    return view(request, *args, **kw)

    lang = get_language() # i18n
    curr = request.session.get('currency', '')
    country = request.session.get('country', '')
    cache_key = f"{view.__module__}.{view.__name__}:{lang}:{curr}:{country}"

    resp = cache.get(cache_key)
    if resp is not None:
    return HttpResponse(resp)

    response = view(request, *args, **kw)
    if response.status_code == 200:
    cache.set(cache_key, response.content, timeout)
    return response
    return wrapper
    return decorator


    def get_cached_products(cache_key, queryset, timeout=CACHE_TIMEOUT_COMMON):
    lang = get_language()
    full_key = f"{cache_key}:{lang}"
    data = cache.get(full_key)
    if data is None:
    data = list(queryset)
    cache.set(full_key, data, timeout)
    return data

    def get_cached_product_variants(product_list, cache_key='product_variants', timeout=CACHE_TIMEOUT_COMMON):
    lang = get_language()
    full_key = f"{cache_key}:{lang}"
    data = cache.get(full_key)
    if data is None:
    data = []
    for product in product_list:
    if product.is_variant:
    data.extend(product.get_variant)
    cache.set(full_key, data, timeout)
    return data

    def get_all_cached_data():
    featured_products = get_cached_products(
    'featured_products',
    Product.objects.filter(status=True, visible=True, is_featured=True)
    .exclude(image='')
    .only('id','title','slug','image')[:8]
    )
    popular_products = get_cached_products(
    'popular_products',
    Product.objects.filter(status=True, visible=True)
    .exclude(image='')
    .order_by('-num_visits')
    .only('id','title','slug','image')[:4]
    )
    recently_viewed_products = get_cached_products(
    'recently_viewed_products',
    Product.objects.filter(status=True, visible=True)
    .exclude(image='')
    .order_by('-last_visit')
    .only('id','title','slug','image')[:5]
    )
    variants = get_cached_products(
    'variants',
    Variants.objects.filter(status=True)
    .select_related('product')
    .only('id','product','price','status')
    )
    product_list = get_cached_products(
    'product_list',
    Product.objects.filter(status=True, visible=True)
    .prefetch_related('product_variant')
    )
    return featured_products, popular_products, recently_viewed_products, variants, product_list

    def get_cart_info(user, request):
    if user.is_anonymous:
    return {}, 0, [], 0, []
    cart = Cart(request)
    wishlist = list(UserWishList.objects.filter(user=user).select_related('product'))
    shopcart_qs = ShopCart.objects.filter(user=user).select_related('product','variant')
    shopcart = list(shopcart_qs)
    products_in_cart = [item.product.id for item in shopcart if item.product]
    total = cart.get_cart_cost()
    comparing = len(request.session.get('comparing', []))
    compare_var = len(request.session.get('comparing_variants', []))
    total_compare = comparing + compare_var
    if len(cart) == 0:
    shopcart = []
    return {
    'cart': cart,
    'wishlist': wishlist,
    'shopcart': shopcart,
    'products_in_cart': products_in_cart,
    }, total, wishlist, total_compare, shopcart

    @cache_anonymous_page(3600)
    def frontpage(request):
    featured_products, popular_products, recently_viewed_products, variants, product_list = get_all_cached_data()
    var = get_cached_product_variants(product_list)
    cart_ctx, total, wishlist, total_compare, shopcart = get_cart_info(request.user, request)
    context = {
    'featured_products': featured_products,
    'popular_products': popular_products,
    'recently_viewed_products': recently_viewed_products,
    'variants': variants,
    'var': var,
    **cart_ctx,
    'subtotal': total,
    'total_compare': total_compare,
    }
    return render(request, 'core/frontpage.html', context)


    I installed django debug toolbar and it shows time ~40 ms for a cached frontpage. My server has 2 CPUs. When i try perfomance testing using locust I get around 3 RPS. I thought i would get around 2CPU*(1000/40) ~ 50 RPS.

    I run my server using this command inside docker container:

    gunicorn main.wsgi:application
    -k gevent
    --workers 6
    --bind 0.0.0.0:8080
    --worker-connections 1000
    --timeout 120


    Also i use psycopg2 with psycogreen wsgi.py starts with this:

    from psycogreen.gevent import patch_psycopg
    patch_psycopg()


    What am i doing wrong? Why can't handle more RPS?

    Continue reading...

Compartilhe esta Página