<commit_before>---
layout: post
title: Ditching Django REST Framework Serializers for Serpy
author: clark
---

This is the story of how we ditched [Django REST Framework
Serializers](http://www.django-rest-framework.org/api-guide/serializers/) for
[serpy](https://github.com/clarkduvall/serpy) and got a performance boost in almost all of our API
endpoints.

Here at [BetterWorks](https://betterworks.com), we use a lot of tools to keep tabs on our app and
make sure our API is performing quickly and efficiently. In production, we use [New
Relic](http://newrelic.com), and locally we use tools like [Django Debug
Toolbar](https://django-debug-toolbar.readthedocs.org) and Python's
[profilers](https://docs.python.org/2/library/profile.html). Many times, an endpoint is executing
too many queries, or the queries are inefficient. These problems are usually pretty easy to solve.
Other times, our Python code is the problem.

As I was profiling some of our slower APIs, I went through my checklist:

  - Too many SQL queries happening? __NOPE__
  - Slow SQL queries happening? __NOPE__
  - A lot of obvious work being done in Python? __NOPE__

A typical view I was seeing this pattern for looked something like this:

```py<commit_msg>Fix weird wording<commit_after>---
layout: post
title: Ditching Django REST Framework Serializers for Serpy
author: clark
---

This is the story of how we ditched [Django REST Framework
Serializers](http://www.django-rest-framework.org/api-guide/serializers/) for
[serpy](https://github.com/clarkduvall/serpy) and got a performance boost in almost all of our API
endpoints.

Here at [BetterWorks](https://betterworks.com), we use a lot of tools to keep tabs on our app and
make sure our API is performing quickly and efficiently. In production, we use [New
Relic](http://newrelic.com), and locally we use tools like [Django Debug
Toolbar](https://django-debug-toolbar.readthedocs.org) and Python's
[profilers](https://docs.python.org/2/library/profile.html). Many times, an endpoint is executing
too many queries, or the queries are inefficient. These problems are usually pretty easy to solve.
Other times, our Python code is the problem.

As I was profiling some of our slower APIs, I went through my checklist:

  - Too many SQL queries happening? __NOPE__
  - Slow SQL queries happening? __NOPE__
  - A lot of obvious work being done in Python? __NOPE__

An example of a typical Django view where I was seeing this pattern looked something like this:

```py
{'fraction_non_alphanumeric': 0.08176352705410822, 'fraction_numerical': 0.0008016032064128256, 'mean_word_length': 4.437908496732026, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 8, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2372222', 'n_tokens_mistral': 723, 'n_tokens_neox': 680, 'n_words': 327}