The journey of a Django app: from startup, to scale up, to enterprise

This video features Daan Vielen at Django Day Copenhagen 2023 in Copenhagen, Denmark.

The journey of a Django app: from startup, to scale up, to enterprise
0:30:19
Published October 8, 2023
1,319 views

"The journey of a Django application: from startup, to scale up, to enterprise" by Daan Vielen at Django Day Copenhagen 2023. Talk description at: https://2023.djangoday.dk/talks/daan/

Summary

Daan Vielen traces SignRequest’s Django application from a small bootstrapped e-signature startup to its integration into Box. Django’s batteries-included approach, secure defaults, admin, storage, ORM, migrations, and background-task integration let a small team ship quickly while scaling with load balancers, Celery workers, Redis, queues, autoscaling, and a single monolith rather than premature microservices. After acquisition, Sign became a Box microservice, adopting Box authentication, file permissions, a backend-for-frontend, GCP Cloud Run, Pub/Sub, and extensive end-to-end testing while retaining much of Django’s core. Vielen argues that architecture should follow team size, business scale, and economics: keep the monolith and optimize only when needed, then consider separate services or faster components such as Java, C, or FastAPI when the organization and workload justify them.

Key takeaways

  • Django’s built-in components and secure defaults help startups focus on product features instead of rebuilding common infrastructure.
  • SignRequest scaled its Django monolith horizontally with separate web and background workers, prioritized queues, suitable hardware, and autoscaling.
  • The team rejected microservices while it was small because the added operational and code complexity offered little benefit.
  • After Box acquired SignRequest, the application became a service integrated with Box authentication, file storage, permissions, and GCP infrastructure.
  • The team preserved familiar developer interfaces, including task decorators and request.user, even when replacing Celery and AWS with custom Pub/Sub and cloud components.
  • Future changes such as FastAPI, other languages, or independent microservices should be justified by scale, reuse, performance, and infrastructure costs.

Summarised automatically from the transcript.

Transcript

3,839 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:09

Speaker 1: All right. Yes, welcome back. On stage we have Dan ready And your talk, Journey of a Django application , from startup to scale up to enterprise. Can you do that in twenty five minutes?

0:31

Speaker 2: I uh try. Maybe I will start talking really fast, but that's like uh to get through all my slides. So

0:39

Speaker 1: let's give Dan a big big hand

0:46

Speaker 2: All right, thank you. So yeah, my name is Dan Vielen. Um I'm from the Netherlands and I'm a developer at Box. And Box is a US company from Redwood City, California, but they also have an office in Amsterdam. And they were very kind to let me travel today to Copenhagen to tell you all Nice story. So, being at the Django conference, I will tell a bit about Django. So, Django was and is still the technical backbone of the sign application. Uh for bucks. The company bought sign requests, and sign requests went from a bootstrapped startup to being a scale-up

1:32

Speaker 2: to being acquired by a big company. But first, I want to talk about me. So, my first professional Django project I did 10 years ago. So I was hired as a freelance developer to create a backend for a typing course. It's a type course for kids under 12 to learn how to type with the help of Tone Not Duck. And the front end, it was implemented in Flash. So show of hands, who knows flash still? Okay, okay. It's uh yeah quite some people still who can remember this Nowadays it's all replaced with hip JavaScript frameworks. But basically, from

2:18

Speaker 2: that moment in 2012, all my freelance gigs were done in Django So fast forward a couple of years, I got a call from one of the founders of this company, signrequest. com, it's still live, that they needed a Django developer. Sign request does e-signatures. So you upload the PDF. Say I want a signature there and there from this person. You fill in an email address and up it goes. And then you get a Digital signed document that actually holds up in court. Um and for me personally I was happy to start working in a startup. That

3:03

Speaker 2: was ready to scale up, or actually that was able to pay me. So I was uh one of the first hires for sign requests and uh it gave me some very nice insights how a tech stack can change like with uh how the company grows so Django had sign requests in the early days so but First let me tell a bit about why Django is very good for a startup. So At a startup you need to be quick on your feet. So in the early days, you can early stage of a company, it can change per day for what is important.

3:49

Speaker 2: and the direction direction of the company can pivot quite quickly. So it's important to have a framework that allows you to enable for that And also one thing really nice about Django are the batteries that are included Don't have to tell this audience, but like their session management, ORM, database migration, file storage, all those components, they are following a shared nothing principle of architecture. uh that will make it easy to swap it out depending for your needs at what your application needs. And having that clear separation between those different parts means it can also scale for increased traffic by just adding hardware at any level.

4:38

Speaker 2: So if you have problem with your database load, you can just add more hardware to your database. If you have problem caching servers. Application servers. So it is very scalable, and that's also what it proved to be in the years that from the start. One thing that's also very nice about Django in the early days, it's secure by default. It's incredibly easy to make a mistake if you start implementing encryption for your password yourself. Um so By default, by just using the default components, it protects developers for SQL injection, click jacking, cross-site

5:28

Speaker 2: request forgery, cross-site scripting. Django just takes care of that. And It takes care of the boring stuff in web development. Like why would you want to write your own URL parser? I don't know. But people sometimes do. You can really focus on just adding value to the company. You can add uh focus on writing features that brings in new customers and that make the company grow. And one of the best things about Django, in my opinion

6:13

Speaker 2: It is boring. It is proven technology. It has been around for many, many years. It has been proven to like Big companies are built on this technology. There's a process for everything, there's a process for vulnerability reports, etc. uh that that that you don't get with all those new hip frameworks that are just barely started with. Also of course will be use cases to use those but for the base of a company this is like Really good. So with all those batteries included, uh

6:59

Speaker 2: Django comes with a big set of features that you don't need to write for yourself. So as you can if you want to, uh you can decide to write your own caching framework. Okay, but who would want to? Especially in the early stage. So this is also one of the things that people often don't like about Django. So developers feel like, oh, it's so much extra weight. Uh I only need this small endpoint, so I just use Tim Flask. Oh I need the database. I use SQL Alchemy. Oh I need the template. I will use Jinja. So in the end often they are just building their own Django, but without the defaults that Other developers know how to use and it will be very difficult to add new developers to that self-invented stack.

7:47

Speaker 2: Okay, so back to sign request. So sign request used in the early days many of those features. Um One of them is obviously the Django Admin. So the Django Admin was used for support until like quite quite recent. In the end it was replaced by a custom support dashboard where it was more focused around the customer instead of around database tables. But This worked really well in the early stage and so there was no developer spending a month on writing a support database uh support

8:32

Speaker 2: uh dashboard And that developer can spend time on adding new features, what brings in new customers. Also, yeah, you can imagine some requests uh it handles a lot of files. This was also very easily implemented by just using the uh Django storages and having a file field. Not much time and effort needed to be used in implementing that. We could just focus on adding code and value. Okay, one thing that SignRequest

9:18

Speaker 2: didn't use were the Django templates. So from the beginning on, um there was like a frontend Framework used. So Angular was the first front-end framework that was used. Boiler Alert, there were more frameworks used over the years. But Uh also the backend code was not more complicated than needed at that time. It just returned to JSON. So if we go back to the batteries included , basically sign requests use everything except templates, forms, and the message framework. All those other things they had a place in uh in in in the infrastructure.

10:04

Speaker 2: So then sign requests became popular. So it started like this. So we have like a couple of users, a web server and a database. So then We got a lot of users. So that one web server was not able to do everything anymore. And it was like um Yeah, we needed to scale extra extra hardware. So then okay, you add a load balancer and more servers. Merging all the PDFs like yeah, the the the signatures need to be merged and a new PDF, uh certificate need to be applied, emails need to be sent. Doing all that from a web server was also not very scalable.

10:49

Speaker 2: So of course we started using salary with a Redis queue and workers looking at the Redis queue if there was a task for them for them to do. So there were like infrastructure started looking like this. So a lot of web servers and a lot of background task servers that take care of those things. Some tasks are more important than other tasks. For instance, if a customer decides to send out ten thousand PDFs for all their customers to sign Yeah, you don't want to whole get that clogging up your whole um queue. So we decided to go with low prior tasks, high prior task, so that we can extra server capacity to high prior tasks.

11:38

Speaker 2: Bit less to the low prior task. And in the end we all made this auto scaling Because in this day and age you can just go to AWS and say like oh give me just as many hardware as I want for my customers because well our business model actually works. So with AWS Fargate at auto scale , also the background task workers they were scaling based on the number of messages in the queue. So if there was like suddenly 10,000 documents to be signed that automatically new servers were added to the to the queue. But In the end, it were all just

12:24

Speaker 2: containers with the Django code. So we didn't have 20 microservices that did all this stuff. No, it was still like This one monolith of Django code that did everything. So and Splitting those queues up didn't only make it easy to scale horizontally, it also made that you can define proper hardware for the jobs. So sending email doesn't take doesn't need a lot of CPU, but converting a doc X does. This is a stage where many companies decide, like, oh, we need to do microservices. Um we decided not to. Especially um that microservice they solve a lot of things.

13:10

Speaker 2: One of them is like You can handle the load better by scaling the services independently, but we already had that covered. And Also, it doesn't really make sense if your team is like six people big. So with a small team, um There was like no advantage in going to microservices. Uh it would only add extra complexity to the code base. Because in the end, uh it was just like writing Python So if you had like a task that needed to send out an email, you just added like okay this is a email task

13:57

Speaker 2: and the infrastructure itself would would solve it. So There was like no incentive for us to build a send this email microservice. Another thing that happens when the company grows is we make more customers, you get requests from companies to connect their single sign-on uh service of choice. Also, Django uh together with SocialOff brings this more or less out of the box. So in the end, this is basically what the

14:43

Speaker 2: how the batteries included situation look like. Yes, we still use all those things, but we extended authentication with the social off. So the admin, we extend it with a custom customer dashboard. sessions, we modified it to provide extra location info and where we could send an email to a customer like, hey, we haven't seen you logging in from this IP address before Is this all okay that are you really in North Korea? So um yeah So the file upload, we extend it with S3. A testing, it w was like a mix of the default Django test and Py test. Sending emails, okay. Custom background task to

15:30

Speaker 2: plans on emails at certain points. And well, the front end. We rewrote everything to work in view. Then John Django at Boxheim Um developing software with a big team makes a big difference because Sign request had nine developers and sign at the moment has 30 but box itself has 2500 so we were becoming part of this big corporation So also funny story, like

16:15

Speaker 2: I left the company sign requests. I went to work for another company as being a freelancer for a year and then one of the founders told me like hey please don't take any new freelance jobs we need you soon something really cool is happening and then I a couple of days later I read in the newspaper box bought sign request So I congratulated every to everyone. But yeah, they said like okay, we have three months to get this application of sign request in box and we can use all the help. So we need to integrate everything And yeah, so where I was saying about the microservices.

17:01

Speaker 2: So in the end, Sign is like a microservice now in the box infrastructure. So it it all has to do with skill. So it's it's like at that skill it makes sense to have like a sign microservice and also like with that many developers working on it Also one thing that's weird working for such a big corporation suddenly is that yeah you can read about the feature you're working on in Bloomberg. Uh that that like okay like next quarter we will release Bad Sand and I'm like okay I'm working on batch send no pressure so but what did that do for the rest for our code

17:47

Speaker 2: So we were introducing files. So I don't know if everybody here is no box, but box is well very good with files. It's their core business So companies have super control about who can access their files and who not. It's file stories for the hospitals, accounting firms, movie studios, companies that are really, really in trouble if something bad happens to their files So we were storing everything in S3 and we now needed to implement that to work with box And then suddenly you have to do deal with a lot of events that can things that can happen with those files. So suddenly permissions can change on your file, shells can be shared, unshared.

18:32

Speaker 2: All those things you need to be aware of and what that does for your signature request because in the end box wanted just to have like your file explorer, right mouse click, I want a signature on that. So one thing we also did to make this all work. We introduced a back end for front end. So this is basically the things that we don't want to do in Django. anymore but we start using the box system for that. So it's like authentication That is done by box, like we don't want to have like a separate authentication for the box sign

19:20

Speaker 2: project. The BFF tells Django application, okay, this file you can do this and this with. So really roughly The user talks with the BFF and the BFF they talk with the whole infrastructure at b uh at that box so with the authentication, our sign backend, other files And to scale that up, oh yeah, also one thing, the box wanted us to have it in GCP and we were in AWS. So instead of AWS Fargate, it now runs on GCP Cloud

20:06

Speaker 2: Run. All the workers are CloudRun workers The BFF is a Kubernetes cluster. And well, very simplified version, but then you have like the other services box you have to deal with, the permissions, the metadata of the files. search shield that can protect your files. So for our Django application it meant that Uh we needed to make sure hey which user is talking to us. So that was like solved with a JWT JWT token. And yeah, like we knew if the request came from the BFF and we can decode the JWT token, then for our service

20:52

Speaker 2: it's like a locked-in user. And we authenticate that user. So in our application there was not more change than uh it still kept on working. So we can still do request. user everywhere. Uh async tasks, we moved that to G C P PubSup. Um It's like the GCP uh uh version of the background tasks. We have like publish the two topics and then you have a consumer sends it to a cloud run instance to handle the task but in our code we still have like the add

21:38

Speaker 2: task uh we just offload it differently So in the end, of all those batteries included, we still use the ORM , we still use database migrations, we still use the URL scheme, although it's now gated by the uh BFF. Authorization, well, that's done in uh in the BFF. Caching, um we only cache it uh locally, so there's no shared cache anymore. Uh testing, we added a lot, a lot of tests. Um a lot. Especially end-to-end tests because you suddenly have to uh be aware what files like being served from the box file system

22:25

Speaker 2: how that can react so you have to like add a lot of end-to-end tests on top of that. about all the lot of tests we already had of course in the back end and front end. Internalization and localization is still done the same way. And even sending emails, although that will change soon. So for the future, we know we have to we get more and more users. sign is getting adopted by the box users uh quit more and more quickly plus we know that box is growing like it's like we know it will grow um So we also might reach the stage now finally

23:10

Speaker 2: that we might optimize by rewriting some of the Python functionalities in a different language. And we might end up in a situation where we will split up background task to become independent microservices because other Teams at box want to use it. They also might want to sign a document. So it makes sense to create a mini sign microservice. We're currently investigating if we can replace the Django fuse with FastAPI. That can also be interesting. And we will be adding like a ton and ton of more new features. That's it.

24:02

Speaker 1: Thank you so so much and you finished perfectly on time.

24:08

Speaker 2: I practiced.

24:12

Speaker 1: Could learn something from that. That means uh there is time for questions. I think

24:22

Speaker 3: but by a millisecond. Uh I just want to ask about PubSub. You mentioned that Uh you switch from salary to PubSub, right? But you're still uh you're still using the task decorator?

24:37

Speaker 2: Yeah, we still use the same um way of of of of of calling it but like the code behind it it's all custom now so we publish a message to PubSub but we still wanted to have that benefit for our developers that they can just use a decorator. Okay, this method needs to run in a separate task. So we we build a way around it. So not much of salary is used anymore, but the interface of salary we still use.

25:11

Speaker 3: Yeah, uh so do you use your own salary fork for that?

25:15

Speaker 2: Well w sort of like we basically intercept like before it goes in the salary system we intercept the message before that and then handle this from there.

25:28

Speaker 3: Okay, yeah, thank you

25:32

Speaker 4: Hi, uh uh great talk, thanks. Um uh m in the last slide you mentioned uh that you are considering moving from Django jeep views to fast API.

25:45

Speaker 2: Yes. Yes. Um uh that that that's um up for discussion so we we are investigating that it's like uh uh I I kind of like the especially with types I I like how how that is done there um So we're we're investigating if if that that's doable. So like it's it's more like also you don't have to use everything that Django provides. So everything is up to table that can be replaced if there are additions. additional benefits so we see some benefits but they we need to make sure they don't outweight the negatives

26:34

Speaker 2: Um hi, great talk. Um when you had this Django monolith that became bigger and bigger, how do you manage to separate The

26:43

Speaker 5: context so you know avoiding that everything becomes a big blob of intertwined Django apps

26:50

Speaker 2: great question. It's that that that is difficult indeed. Um it also uh made sure that that the apps don't depend too much on each other. Um but in the end it doesn't really matter because it's still the same Django container that runs at different places. in the infrastructure. So the tasks they can use everything that is in the monolith, but it's just runs at at that uh at a different place in different infrastructure depending on the needs and you set optimizing still there for that specific task. Hope that answers your question.

27:36

Speaker 1: Yep. Yeah, great talk.

27:38

Speaker 6: Thank you. Um I think we uh where I work we have this kind of the same situation, not we haven't been born or anything like that. Um and I think we have kind of the same observations that you have. About the optimizations, have you considered uh you know things like PyPy or Cyton or, you know Some of these that you know don't require you to you know use a different language?

28:05

Speaker 2: Yeah, yeah, for sure. Like when and and and we um Um definitely look at at those kind of things. Um but it's also like a trade-off and especially in the startup phase Do you start optimizing for 100 milliseconds faster performance or do you spend the resources on building a new feature? And it it's also like just simple economics. Like, is it worth spending a the developer making this endpoint 50 milliseconds faster? Or that can we make that money back? So uh but but at the scale that box is at that we reach that point quicker because it It's like more hardware is used and the

28:51

Speaker 2: bill of the hardware becomes more significant and then an optimization like that can really be benefit. Just

29:02

Speaker 6: an added uh question. Uh different language, what would that potentially be?

29:08

Speaker 2: Um so for instance uh like Like merging the PDFs. We already do that in Java. Um I know Instagram replaced a lot of Python code with custom C code just to make it those milliseconds faster. Yeah, it working at a bigger company you know the roadmap better than at the startup. So you can really plan for okay what what is needed and what is coming. So yeah, we have to find there the right balance in optimizing or not

29:58

Speaker 1: Yeah, I think those were the questions. So Another celebration of another talk. Maybe it looks bad how it's folding over the door. And we're just getting our next one.

Questions this talk answers

Why is Django a good choice for a startup?

Django lets a small team move quickly because it includes common features such as authentication, sessions, the ORM, migrations, storage, and an admin interface. Its secure defaults and proven, boring technology let developers focus on product features instead of rebuilding web infrastructure.

Discussed at 3:03

How do you scale a Django application as traffic and background work increase?

SignRequest added load balancing and more web servers, then moved PDF processing, email, and other expensive work into Celery workers backed by Redis. Separate priority queues, autoscaling, and task-specific hardware allowed the system to scale while keeping one Django monolith.

Discussed at 10:29

Why did SignRequest keep a Django monolith instead of switching to microservices?

The existing queues already provided independent scaling, and the team was only about six people, so microservices would have added complexity without much benefit. Tasks could remain ordinary Python code while the infrastructure routed them to suitable workers.

Discussed at 13:10

How did Django change when SignRequest became part of Box?

The application became a service inside Box's larger infrastructure: Box handled authentication and file-related concerns through a backend-for-frontend, while the Django service ran on GCP Cloud Run and used Pub/Sub for asynchronous work. Django still handled core pieces such as the ORM, migrations, URL routing, and application logic.

Discussed at 18:32

How can you migrate from Celery to Google Pub/Sub without changing how developers define tasks?

The team kept the Celery-style task decorator and interface, but intercepted tasks before they entered Celery and published them to Pub/Sub instead. This preserved the simple developer experience while replacing most of Celery's implementation.

Discussed at 24:37

Why is SignRequest considering replacing Django views with FastAPI?

The team sees potential benefits in FastAPI, particularly its approach to typing, but is still investigating whether those benefits outweigh the costs. Django components can be replaced selectively when there is a clear advantage rather than replacing the whole stack by default.

Discussed at 25:45

How do you keep a growing Django monolith from becoming a tangled blob?

The team tried to prevent Django apps from depending too heavily on one another, but the monolith's shared container meant tasks could still access its code. Different infrastructure placements and task-specific optimization provided separation of operation rather than fully separate codebases.

Discussed at 26:50

When should a Django company optimize Python code or rewrite parts in another language?

Early-stage teams should weigh small performance gains against spending developer time on product features. At Box's scale, hardware costs become significant enough that optimizations can pay off; examples include implementing PDF merging in Java or replacing hot Python paths with C or another language.

Discussed at 28:05

Presenters

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from Django Day Copenhagen