# Primary key for custom User model

**URL:** <https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889>\
**Category:** Using Django\
**Created:** [April 10, 2020, 6:32am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889 "2020-04-10T06:32:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![psyonara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/psyonara/32/993_2.png) [@psyonara](https://forum.djangoproject.com/u/psyonara)\
**Post date:** [April 10, 2020, 6:32am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/1 "2020-04-10T06:32:49Z")

</div>

Hey everyone,

I’m busy changing over to a UUID as a primary key on my models, but also have a custom User model, and was wondering if it’s safe to do the same on the User model. I don’t know if Django uses the primary key internally in any way, and whether that would then be adversely affected by changing the primary key field.

Any thoughts on that?

Thank you!

---

<div class="post-metadata">

**Author:** ![adamchainz](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/adamchainz/32/26_2.png) [@adamchainz](https://forum.djangoproject.com/u/adamchainz)\
**Post date:** [April 10, 2020, 7:23am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/2 "2020-04-10T07:23:27Z")

</div>

Hi @psyonara,

Welcome to the forum.

Why are you changing everything over to UUID PK’s? They won’t perform as well in your database as autoincrement ID’s. They use more storage space and because they are distributed randomly, they reduce the effect of your DB caching tables in memory.

Anyway I _think_ you should be able to change the user PK. It should only be referred to as typeless PK in `django.contrib.auth` . I believe [djangae](https://github.com/potatolondon/djangae) gets away with random string ID’s for everything, because that’s what google app engine supports.

Hope that helps!

---

<div class="post-metadata">

**Author:** ![psyonara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/psyonara/32/993_2.png) [@psyonara](https://forum.djangoproject.com/u/psyonara)\
**Post date:** [April 10, 2020, 7:52am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/3 "2020-04-10T07:52:56Z")

</div>

Thank you, @adamchainz.

Performance is not an issue in my case, so that is not a worry. Using a UUID presents more advantages than disadvantages for what I need, so I’m happy to go that route. One article that influenced my decision most:  
[https://devforth.io/blog/why-your-software-should-use-uuids](https://devforth.io/blog/why-your-software-should-use-uuids)

I decided to go with KSUIDs: [https://github.com/saresend/KSUID](https://github.com/saresend/KSUID)  
These can then be encoded as base62, and then only use up 27 characters, instead of the 40 that normal UUIDs use.

Anyway, thanks for your feedback on the User model. The reason why I was wondering: if the user ID is ever exposed on the front-end (even if just in a request URL or POST), a non-incremental one would not reveal anything potentially sensitive.

I think I’ll probably give it a try to replace the User PK with a UUID, and see if I run into any issues.

Thanks again.

---

<div class="post-metadata">

**Author:** ![adamchainz](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/adamchainz/32/26_2.png) [@adamchainz](https://forum.djangoproject.com/u/adamchainz)\
**Post date:** [April 10, 2020, 9:06am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/4 "2020-04-10T09:06:37Z")

</div>

> [@psyonara](#):
>
> One article that influenced my decision most:  
> [Why your software should use UUIDs](https://devforth.io/blog/why-your-software-should-use-uuids)

The sharding argument there is not very applicable to most use cases. Also you don’t want clients generating ID’s, whilst in theory they’ll be independent, in practice many things can remove sources of randomness.

Consider the opposite positions from Basecamp, who _still_ have a single DB server:

> **[Mr. Moore gets to punt on sharding](https://signalvnoise.com/posts/1509-mr-moore-gets-to-punt-on-sharding)**
>
> Sharding is a database technique where you break up a big database into many smaller ones. Instead of having 1 million customers on a single, big iron machine, you perhaps have 100,000 customers on 10 different, smaller machines.
> 
> 
> The general...

> **[Three years later, Mr. Moore is still letting us punt on database sharding](https://signalvnoise.com/posts/3089-three-years-later-mr-moore-is-still-letting-us-punt-on-database-sharding)**
>
> Three years ago, I wrote about how improvements in technology keep allowing us to punt on sharding the Basecamp database. This is still true, only more so now.
> 
> 
> We’ve grown enormously over the last three years but RAM keeps getting cheaper and...

I forgot to post in previous message about hashids, which are auto increment PK’s with some obfuscation: [GitHub - nshafer/django-hashid-field: Django Model Field that uses Hashids to obscure the value](https://github.com/nshafer/django-hashid-field) .

Anyway, this is a topic that’s dear to me, I need to go write a blog post on it 😂

If you continue with UUID PK’s, do post about any problems you encounter.

Thanks,

Adam

---

<div class="post-metadata">

**Author:** ![psyonara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/psyonara/32/993_2.png) [@psyonara](https://forum.djangoproject.com/u/psyonara)\
**Post date:** [April 10, 2020, 12:48pm UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/5 "2020-04-10T12:48:24Z")

</div>

Thanks for your thoughts, @adamchainz. As a result I will think through this one more time to carefully consider the pro’s and con’s.

I must say that I failed to mention in my last reply that the sharding was really not part of my reasoning, since I don’t expect to ever have to shard, just like Basecamp (thanks for those links, I dig the Basecamp gang).

And thanks for the hashid link, that looks really interesting. Definitely having a look at that right now.

I eagerly expect your blog post on the topic. 😉

---

<div class="post-metadata">

**Author:** ![psyonara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/psyonara/32/993_2.png) [@psyonara](https://forum.djangoproject.com/u/psyonara)\
**Post date:** [April 12, 2020, 3:25pm UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/6 "2020-04-12T15:25:34Z")

</div>

While I didn’t end up switching my user model to a UUID-type primary key, I did switch my own models over. At first I started making migrations to change over step-by-step, but the foreign key relations were a major pain. In the end I just exported my data, re-created the database, and then imported the data again with a custom script which handles the relations with the new keys. Worked like a charm. I’ll report back on any future difficulties I might experience as a result of the UUID primary keys.

---

<div class="post-metadata">

**Author:** ![psyonara](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/psyonara/32/993_2.png) [@psyonara](https://forum.djangoproject.com/u/psyonara)\
**Post date:** [July 3, 2020, 5:26am UTC](https://forum.djangoproject.com/t/primary-key-for-custom-user-model/1889/7 "2020-07-03T05:26:13Z")

</div>

As promised, some feedback after almost 3 months.

No problems so far. 🙂
