# Keeping the socket out of async tasks

If your `assign_async/3` callback reads `socket.assigns.user_id`, it captures the whole socket, even though the query only needs an ID:

```elixir
# Captures the socket
assign_async(socket, :user, fn ->
  {:ok, %{user: Accounts.get_user!(socket.assigns.user_id)}}
end)

# Extract the ID before creating the callback
user_id = socket.assigns.user_id

assign_async(socket, :user, fn ->
  {:ok, %{user: Accounts.get_user!(user_id)}}
end)
```

The second callback captures `user_id`, so the task receives that value instead of the socket and its other assigns.

Moving the assignment inside the callback won't help, because the function still captures `socket`. Extract what you need before `fn ->`. The same applies to callbacks passed to `start_async/3` and `Task.async/1`.

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-async-operations


---

Created by: almirsarajcic
Date: October 30, 2026
URL: https://elixirdrops.net/d/hXwrJuoA
