I’ve been able to figure out how to use instrument. For future references. Run a script like this to get the best information out: elixir --erl “+Muatags true” sqlite_reproduction.exs
So I ran :instrument.allocations before the query and after the query, and thse are the only significant changes that I see:
So this line:nif_internal: {1999, 438, 40, 10, 10, 9, 15474, 0, 0, 10, 10, 1, 0, 0, 0,
0, 0, 0}
Running with exqlite gives me no such thing:

For completeness here is the full script that I used:
Mix.install([
{:ecto_sql, "~> 3.13.2"},
{:ecto_sqlite3, "~> 0.22"},
{:exqlite, "~> 0.33.1"}
])
Application.put_env(:myapp, Repo, database: "./dev.db")
defmodule Repo do
use Ecto.Repo,
otp_app: :myapp,
adapter: Ecto.Adapters.SQLite3
end
defmodule Main do
@sql ~s"""
SELECT
s0."id",
e1."id",
e1."type",
e1."data",
e1."inserted_at",
s0."stream_id",
s0."stream_version"
FROM "stream_events" AS s0
INNER JOIN "events" AS e1 ON s0."event_id" = e1."id"
WHERE s0."stream_id" = '$all' AND s0."stream_version" >= 0
ORDER BY s0."id" DESC
LIMIT 1
"""
def sqlite do
IO.inspect "before"
print_memory()
save_allocations("./before_sqlite")
{:ok, _} = Repo.start_link([])
_s1 = Ecto.Adapters.SQL.query!(Repo, @sql, nil)
IO.inspect "after"
print_memory()
save_allocations("./after_sqlite")
end
def exqlite do
IO.inspect "before"
print_memory()
save_allocations("./before_exqlite")
{:ok, conn} = Exqlite.Sqlite3.open("./dev.db")
{:ok, statement} = Exqlite.Sqlite3.prepare(conn, @sql)
{:row, _results} = Exqlite.Sqlite3.step(conn, statement)
IO.inspect "after"
print_memory()
save_allocations("./after_exqlite")
end
defp print_memory() do
IO.inspect "memory: #{:erlang.memory(:total) / 1_000_000}"
end
defp save_allocations(name) do
{:ok, x} = :instrument.allocations
File.write!(name, inspect(x, limit: :infinity, pretty: true))
end
end
# Main.sqlite()
Main.exqlite()





















