Back to Blog Home

How Sentry uncovered an N+1 issue in djangoproject.com

Shana Matthews image

Shana Matthews -

How Sentry uncovered an N+1 issue in djangoproject.com

Sentry recently launched Performance Issues, a feature to help developers discover and fix common performance problems in their projects. We tested this project internally and with alpha users, so when we finally turned it on for all Sentry users, we were delighted (and dismayed) to hear from Carlton Gibson, current Django fellow and great human, that Sentry had:

  1. Detected an N+1 problem in the code for http://djangoproject.com/
  2. Annoyed the heck out of Carlton and other Django maintainers with duplicate Sentry Issues for that same N+1 problem (sorry about that!)

tweet please

djangoproject.com’s N+1 problem

The site’s N+1 problem was in their docs version switcher, and the fix was pretty simple.

docs please

Version with N+1 problem:

@register.simple_tag(takes_context=True)
def get_all_doc_versions(context, url=None):
  """
  Get a list of all versions of this document to link to.
  Usage: {% get_all_doc_versions <url> as "varname" %}
  """
  lang = context.get('lang', 'en')
  versions = []

  # This causes an N+1 query!   for release in DocumentRelease.objects.filter(lang=lang):    version_root = get_doc_root(release.lang, release.version)
    if version_root.exists():
      doc_path = get_doc_path(version_root, url)
      if doc_path:
        versions.append(release.version)
  # Save the versions into the context
  versions = sorted(StrictVersion(x) for x in versions if x != 'dev')
  return [str(x) for x in versions] + ['dev']

Fixed version:

@register.simple_tag(takes_context=True)
def get_all_doc_versions(context, url=None):
  """
  Get a list of all versions of this document to link to.
  Usage: {% get_all_doc_versions <url> as "varname" %}
  """
  lang = context.get('lang', 'en')
  versions = []

  # This is fixed :D   for release in DocumentRelease.objects.select_related('release').filter(lang=lang):    version_root = get_doc_root(release.lang, release.version)
    if version_root.exists():
      doc_path = get_doc_path(version_root, url)
      if doc_path:
        versions.append(release.version)

  # Save the versions into the context
  versions = sorted(StrictVersion(x) for x in versions if x != 'dev')
  return [str(x) for x in versions] + ['dev']

Our duplicate issues bug

All developers write buggy code - even devs at Sentry. Carlton was able to resolve djangoproject.com’s N+1 issue, and with his feedback, we were also able to fix the bug in Sentry that was duplicating N+1 performance issues. You can learn more about our fix in the PR.

another tweet please

Performance issues

Sentry’s Performance Issues feature can currently detect N+1 issues in all Sentry-supported backend languages. If you’re already using Sentry for backend performance monitoring, to detect N+1 issues all you have to do is… nothing. Sentry will automatically detect N+1 problems by default.

Beyond N+1 issues, Sentry performance monitoring will identify slow transactions, spans that could be the bottleneck and how a slowdown in one part of your stack is affecting other parts of your application. Check out our docs to learn more about performance monitoring with Sentry.

Share

Share on Twitter
Share on Facebook
Share on HackerNews
Share on LinkedIn

Published

Sentry Sign Up CTA

Code breaks, fix it faster

Sign up for Sentry and monitor your application in minutes.

Try Sentry Free

Topics

Performance Monitoring

The best way to debug slow web pages

Listen to the Syntax Podcast

Of course we sponsor a developer podcast. Check it out on your favorite listening platform.

Listen To Syntax
    TwitterGitHubDribbbleLinkedinDiscord
© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.