When DEBUG is True, Django records each executed query in connection.queries, holding the SQL text, the parameters and the timing for as long as the connection object lives. In a long-running process this grows without bound and looks exactly like a memory leak, because it is one.
The list is capped only by sys.maxsize in practice; the documented cap applies per connection and is large enough not to help. Management commands that loop over millions of rows are the usual victims, since they run for hours in a single process and nobody thinks of them as a server.
The fix in production is simply DEBUG = False, which disables the recording entirely. For a long-running job that genuinely needs DEBUG on, call django.db.reset_queries() periodically, which is what Django itself does between requests. If the process must run with DEBUG for another reason, confirm the cause before chasing anything else by checking len(connection.queries) after an hour; a number in the millions settles the question immediately.