diff --git a/.gitignore b/.gitignore
index 6ae21e914..62ca61bce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
 /db
 /deps
 /*.ez
+/test/instance
 /test/uploads
 /.elixir_ls
 /test/fixtures/DSCN0010_tmp.jpg
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6bf38ee0..e1604ab3a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 - Users with `is_discoverable` field set to false (default value) will appear in in-service search results but be hidden from external services (search bots etc.).
 - Streaming API: Posts and notifications are not dropped, when CLI task is executing.
+- Creating incorrect IPv4 address-style HTTP links when encountering certain numbers.
 
 <details>
   <summary>API Changes</summary>
@@ -53,24 +54,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ## Unreleased (Patch)
 
+### Fixed
+
+- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
+- Emoji Reaction activity filtering from blocked and muted accounts.
+
+## [2.2.1] - 2020-12-22
+
 ### Changed
+- Updated Pleroma FE
 
 ### Fixed
 
 - Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`.
-- Search: RUM index search speed has been fixed.
 - S3 Uploads with Elixir 1.11.
-- Emoji Reaction activity filtering from blocked and muted accounts.
 - Mix task pleroma.user delete_activities for source installations.
-- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
-- Forwarded reports duplication from Pleroma instances.
+- Search: RUM index search speed has been fixed.
 - Rich Media Previews sometimes showed the wrong preview due to a bug following redirects.
+- Fixes for the autolinker.
+- Forwarded reports duplication from Pleroma instances.
 
-<details>
-  <summary>API</summary>
-- Statuses were not displayed for Mastodon forwarded reports.
+- <details>
+    <summary>API</summary>
+  - Statuses were not displayed for Mastodon forwarded reports.
+  </details>
 
-</details>
+### Upgrade notes
+
+1. Restart Pleroma
 
 ## [2.2.0] - 2020-11-12
 
diff --git a/config/config.exs b/config/config.exs
index 3ccb6a3f5..d6d116314 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -47,7 +47,6 @@ use Mix.Config
 config :pleroma, ecto_repos: [Pleroma.Repo]
 
 config :pleroma, Pleroma.Repo,
-  types: Pleroma.PostgresTypes,
   telemetry_event: [Pleroma.Repo.Instrumenter],
   migration_lock: nil
 
diff --git a/config/test.exs b/config/test.exs
index 2a20a03e7..a85881592 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -47,7 +47,10 @@ config :pleroma, Pleroma.Repo,
   password: "postgres",
   database: "pleroma_test",
   hostname: System.get_env("DB_HOST") || "localhost",
-  pool: Ecto.Adapters.SQL.Sandbox
+  pool: Ecto.Adapters.SQL.Sandbox,
+  pool_size: 50
+
+config :pleroma, :dangerzone, override_repo_pool_size: true
 
 # Reduce hash rounds for testing
 config :pbkdf2_elixir, rounds: 1
@@ -121,6 +124,16 @@ config :tzdata, :autoupdate, :disabled
 
 config :pleroma, :mrf, policies: []
 
+config :pleroma, :pipeline,
+  object_validator: Pleroma.Web.ActivityPub.ObjectValidatorMock,
+  mrf: Pleroma.Web.ActivityPub.MRFMock,
+  activity_pub: Pleroma.Web.ActivityPub.ActivityPubMock,
+  side_effects: Pleroma.Web.ActivityPub.SideEffectsMock,
+  federator: Pleroma.Web.FederatorMock,
+  config: Pleroma.ConfigMock
+
+config :pleroma, :cachex, provider: Pleroma.CachexMock
+
 if File.exists?("./config/test.secret.exs") do
   import_config "test.secret.exs"
 else
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 079823312..9d970a808 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -24,6 +24,8 @@ defmodule Pleroma.Activity do
 
   @primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   schema "activities" do
     field(:data, :map)
     field(:local, :boolean, default: true)
@@ -298,7 +300,7 @@ defmodule Pleroma.Activity do
 
   defp purge_web_resp_cache(%Activity{} = activity) do
     %{path: path} = URI.parse(activity.data["id"])
-    Cachex.del(:web_resp_cache, path)
+    @cachex.del(:web_resp_cache, path)
     activity
   end
 
diff --git a/lib/pleroma/caching.ex b/lib/pleroma/caching.ex
new file mode 100644
index 000000000..766d12d1b
--- /dev/null
+++ b/lib/pleroma/caching.ex
@@ -0,0 +1,19 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Caching do
+  @callback get!(Cachex.cache(), any()) :: any()
+  @callback get(Cachex.cache(), any()) :: {atom(), any()}
+  @callback put(Cachex.cache(), any(), any(), Keyword.t()) :: {Cachex.status(), boolean()}
+  @callback put(Cachex.cache(), any(), any()) :: {Cachex.status(), boolean()}
+  @callback fetch!(Cachex.cache(), any(), function() | nil) :: any()
+  # @callback del(Cachex.cache(), any(), Keyword.t()) :: {Cachex.status(), boolean()}
+  @callback del(Cachex.cache(), any()) :: {Cachex.status(), boolean()}
+  @callback stream!(Cachex.cache(), any()) :: Enumerable.t()
+  @callback expire_at(Cachex.cache(), binary(), number()) :: {Cachex.status(), boolean()}
+  @callback exists?(Cachex.cache(), any()) :: {Cachex.status(), boolean()}
+  @callback execute!(Cachex.cache(), function()) :: any()
+  @callback get_and_update(Cachex.cache(), any(), function()) ::
+              {:commit | :ignore, any()}
+end
diff --git a/lib/pleroma/captcha.ex b/lib/pleroma/captcha.ex
index 6ab754b6f..990003dcd 100644
--- a/lib/pleroma/captcha.ex
+++ b/lib/pleroma/captcha.ex
@@ -7,6 +7,8 @@ defmodule Pleroma.Captcha do
   alias Plug.Crypto.KeyGenerator
   alias Plug.Crypto.MessageEncryptor
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   @doc """
   Ask the configured captcha service for a new captcha
   """
@@ -86,7 +88,7 @@ defmodule Pleroma.Captcha do
   end
 
   defp validate_usage(token) do
-    if is_nil(Cachex.get!(:used_captcha_cache, token)) do
+    if is_nil(@cachex.get!(:used_captcha_cache, token)) do
       :ok
     else
       {:error, :already_used}
@@ -95,7 +97,7 @@ defmodule Pleroma.Captcha do
 
   defp mark_captcha_as_used(token) do
     ttl = seconds_valid() |> :timer.seconds()
-    Cachex.put(:used_captcha_cache, token, true, ttl: ttl)
+    @cachex.put(:used_captcha_cache, token, true, ttl: ttl)
   end
 
   defp method, do: Pleroma.Config.get!([__MODULE__, :method])
diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex
index 97f877595..86d4f6b72 100644
--- a/lib/pleroma/config.ex
+++ b/lib/pleroma/config.ex
@@ -3,14 +3,18 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Config do
+  @behaviour Pleroma.Config.Getting
   defmodule Error do
     defexception [:message]
   end
 
+  @impl true
   def get(key), do: get(key, nil)
 
+  @impl true
   def get([key], default), do: get(key, default)
 
+  @impl true
   def get([_ | _] = path, default) do
     case fetch(path) do
       {:ok, value} -> value
@@ -18,6 +22,7 @@ defmodule Pleroma.Config do
     end
   end
 
+  @impl true
   def get(key, default) do
     Application.get_env(:pleroma, key, default)
   end
diff --git a/lib/pleroma/config/getting.ex b/lib/pleroma/config/getting.ex
new file mode 100644
index 000000000..cc557674c
--- /dev/null
+++ b/lib/pleroma/config/getting.ex
@@ -0,0 +1,8 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Config.Getting do
+  @callback get(any()) :: any()
+  @callback get(any(), any()) :: any()
+end
diff --git a/lib/pleroma/emoji/pack.ex b/lib/pleroma/emoji/pack.ex
index f768af19f..ec97aa652 100644
--- a/lib/pleroma/emoji/pack.ex
+++ b/lib/pleroma/emoji/pack.ex
@@ -20,6 +20,8 @@ defmodule Pleroma.Emoji.Pack do
           name: String.t()
         }
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   alias Pleroma.Emoji
   alias Pleroma.Emoji.Pack
   alias Pleroma.Utils
@@ -415,7 +417,7 @@ defmodule Pleroma.Emoji.Pack do
     ttl_per_file = Pleroma.Config.get!([:emoji, :shared_pack_cache_seconds_per_file])
     overall_ttl = :timer.seconds(ttl_per_file * Enum.count(files))
 
-    Cachex.put!(
+    @cachex.put(
       :emoji_packs_cache,
       pack.name,
       # if pack.json MD5 changes, the cache is not valid anymore
@@ -618,7 +620,7 @@ defmodule Pleroma.Emoji.Pack do
   defp fetch_archive(pack) do
     hash = :crypto.hash(:md5, File.read!(pack.pack_file))
 
-    case Cachex.get!(:emoji_packs_cache, pack.name) do
+    case @cachex.get!(:emoji_packs_cache, pack.name) do
       %{hash: ^hash, pack_data: archive} -> archive
       _ -> create_archive_and_cache(pack, hash)
     end
diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex
index 43e9145be..c848c782c 100644
--- a/lib/pleroma/html.ex
+++ b/lib/pleroma/html.ex
@@ -6,6 +6,8 @@ defmodule Pleroma.HTML do
   # Scrubbers are compiled on boot so they can be configured in OTP releases
   #  @on_load :compile_scrubbers
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   def compile_scrubbers do
     dir = Path.join(:code.priv_dir(:pleroma), "scrubbers")
 
@@ -56,7 +58,7 @@ defmodule Pleroma.HTML do
       ) do
     key = "#{key}#{generate_scrubber_signature(scrubbers)}|#{activity.id}"
 
-    Cachex.fetch!(:scrubber_cache, key, fn _key ->
+    @cachex.fetch!(:scrubber_cache, key, fn _key ->
       object = Pleroma.Object.normalize(activity)
       ensure_scrubbed_html(content, scrubbers, object.data["fake"] || false, callback)
     end)
@@ -105,7 +107,7 @@ defmodule Pleroma.HTML do
     unless object.data["fake"] do
       key = "URL|#{object.id}"
 
-      Cachex.fetch!(:scrubber_cache, key, fn _key ->
+      @cachex.fetch!(:scrubber_cache, key, fn _key ->
         {:commit, {:ok, extract_first_external_url(content)}}
       end)
     else
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 357a3b504..1d756bcd1 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -24,6 +24,8 @@ defmodule Pleroma.Object do
 
   @derive {Jason.Encoder, only: [:data]}
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   schema "objects" do
     field(:data, :map)
 
@@ -189,9 +191,9 @@ defmodule Pleroma.Object do
   def get_cached_by_ap_id(ap_id) do
     key = "object:#{ap_id}"
 
-    with {:ok, nil} <- Cachex.get(:object_cache, key),
+    with {:ok, nil} <- @cachex.get(:object_cache, key),
          object when not is_nil(object) <- get_by_ap_id(ap_id),
-         {:ok, true} <- Cachex.put(:object_cache, key, object) do
+         {:ok, true} <- @cachex.put(:object_cache, key, object) do
       object
     else
       {:ok, object} -> object
@@ -249,13 +251,13 @@ defmodule Pleroma.Object do
   end
 
   def invalid_object_cache(%Object{data: %{"id" => id}}) do
-    with {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do
-      Cachex.del(:web_resp_cache, URI.parse(id).path)
+    with {:ok, true} <- @cachex.del(:object_cache, "object:#{id}") do
+      @cachex.del(:web_resp_cache, URI.parse(id).path)
     end
   end
 
   def set_cache(%Object{data: %{"id" => ap_id}} = object) do
-    Cachex.put(:object_cache, "object:#{ap_id}", object)
+    @cachex.put(:object_cache, "object:#{ap_id}", object)
     {:ok, object}
   end
 
diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex
index 8ae1157df..3ea897c95 100644
--- a/lib/pleroma/reverse_proxy.ex
+++ b/lib/pleroma/reverse_proxy.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.ReverseProxy do
   @failed_request_ttl :timer.seconds(60)
   @methods ~w(GET HEAD)
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   def max_read_duration_default, do: @max_read_duration
   def default_cache_control_header, do: @default_cache_control_header
 
@@ -107,7 +109,7 @@ defmodule Pleroma.ReverseProxy do
         opts
       end
 
-    with {:ok, nil} <- Cachex.get(:failed_proxy_url_cache, url),
+    with {:ok, nil} <- @cachex.get(:failed_proxy_url_cache, url),
          {:ok, code, headers, client} <- request(method, url, req_headers, client_opts),
          :ok <-
            header_length_constraint(
@@ -427,6 +429,6 @@ defmodule Pleroma.ReverseProxy do
         nil
       end
 
-    Cachex.put(:failed_proxy_url_cache, url, true, ttl: ttl)
+    @cachex.put(:failed_proxy_url_cache, url, true, ttl: ttl)
   end
 end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 5a7704ddb..bd4801058 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -81,6 +81,8 @@ defmodule Pleroma.User do
     ]
   ]
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   schema "users" do
     field(:bio, :string, default: "")
     field(:raw_bio, :string)
@@ -246,13 +248,13 @@ defmodule Pleroma.User do
   end
 
   def cached_blocked_users_ap_ids(user) do
-    Cachex.fetch!(:user_cache, "blocked_users_ap_ids:#{user.ap_id}", fn _ ->
+    @cachex.fetch!(:user_cache, "blocked_users_ap_ids:#{user.ap_id}", fn _ ->
       blocked_users_ap_ids(user)
     end)
   end
 
   def cached_muted_users_ap_ids(user) do
-    Cachex.fetch!(:user_cache, "muted_users_ap_ids:#{user.ap_id}", fn _ ->
+    @cachex.fetch!(:user_cache, "muted_users_ap_ids:#{user.ap_id}", fn _ ->
       muted_users_ap_ids(user)
     end)
   end
@@ -1048,9 +1050,9 @@ defmodule Pleroma.User do
   def set_cache({:error, err}), do: {:error, err}
 
   def set_cache(%User{} = user) do
-    Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
-    Cachex.put(:user_cache, "nickname:#{user.nickname}", user)
-    Cachex.put(:user_cache, "friends_ap_ids:#{user.nickname}", get_user_friends_ap_ids(user))
+    @cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
+    @cachex.put(:user_cache, "nickname:#{user.nickname}", user)
+    @cachex.put(:user_cache, "friends_ap_ids:#{user.nickname}", get_user_friends_ap_ids(user))
     {:ok, user}
   end
 
@@ -1073,26 +1075,26 @@ defmodule Pleroma.User do
 
   @spec get_cached_user_friends_ap_ids(User.t()) :: [String.t()]
   def get_cached_user_friends_ap_ids(user) do
-    Cachex.fetch!(:user_cache, "friends_ap_ids:#{user.ap_id}", fn _ ->
+    @cachex.fetch!(:user_cache, "friends_ap_ids:#{user.ap_id}", fn _ ->
       get_user_friends_ap_ids(user)
     end)
   end
 
   def invalidate_cache(user) do
-    Cachex.del(:user_cache, "ap_id:#{user.ap_id}")
-    Cachex.del(:user_cache, "nickname:#{user.nickname}")
-    Cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
-    Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
-    Cachex.del(:user_cache, "muted_users_ap_ids:#{user.ap_id}")
+    @cachex.del(:user_cache, "ap_id:#{user.ap_id}")
+    @cachex.del(:user_cache, "nickname:#{user.nickname}")
+    @cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
+    @cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+    @cachex.del(:user_cache, "muted_users_ap_ids:#{user.ap_id}")
   end
 
   @spec get_cached_by_ap_id(String.t()) :: User.t() | nil
   def get_cached_by_ap_id(ap_id) do
     key = "ap_id:#{ap_id}"
 
-    with {:ok, nil} <- Cachex.get(:user_cache, key),
+    with {:ok, nil} <- @cachex.get(:user_cache, key),
          user when not is_nil(user) <- get_by_ap_id(ap_id),
-         {:ok, true} <- Cachex.put(:user_cache, key, user) do
+         {:ok, true} <- @cachex.put(:user_cache, key, user) do
       user
     else
       {:ok, user} -> user
@@ -1104,11 +1106,11 @@ defmodule Pleroma.User do
     key = "id:#{id}"
 
     ap_id =
-      Cachex.fetch!(:user_cache, key, fn _ ->
+      @cachex.fetch!(:user_cache, key, fn _ ->
         user = get_by_id(id)
 
         if user do
-          Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
+          @cachex.put(:user_cache, "ap_id:#{user.ap_id}", user)
           {:commit, user.ap_id}
         else
           {:ignore, ""}
@@ -1121,7 +1123,7 @@ defmodule Pleroma.User do
   def get_cached_by_nickname(nickname) do
     key = "nickname:#{nickname}"
 
-    Cachex.fetch!(:user_cache, key, fn ->
+    @cachex.fetch!(:user_cache, key, fn _ ->
       case get_or_fetch_by_nickname(nickname) do
         {:ok, user} -> {:commit, user}
         {:error, _error} -> {:ignore, nil}
@@ -1390,7 +1392,7 @@ defmodule Pleroma.User do
         )
       end
 
-      Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
+      @cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
 
       {:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
     end
@@ -1400,7 +1402,7 @@ defmodule Pleroma.User do
     with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
          {:ok, user_notification_mute} <-
            UserRelationship.delete_notification_mute(muter, mutee) do
-      Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
+      @cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
       {:ok, [user_mute, user_notification_mute]}
     end
   end
@@ -2408,7 +2410,7 @@ defmodule Pleroma.User do
           {:ok, UserRelationship.t()} | {:error, Ecto.Changeset.t()}
   defp add_to_block(%User{} = user, %User{} = blocked) do
     with {:ok, relationship} <- UserRelationship.create_block(user, blocked) do
-      Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+      @cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
       {:ok, relationship}
     end
   end
@@ -2417,7 +2419,7 @@ defmodule Pleroma.User do
           {:ok, UserRelationship.t()} | {:ok, nil} | {:error, Ecto.Changeset.t()}
   defp remove_from_block(%User{} = user, %User{} = blocked) do
     with {:ok, relationship} <- UserRelationship.delete_block(user, blocked) do
-      Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
+      @cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
       {:ok, relationship}
     end
   end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 2e25412c6..54d1a2350 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -32,6 +32,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   require Logger
   require Pleroma.Constants
 
+  @behaviour Pleroma.Web.ActivityPub.ActivityPub.Persisting
+
   defp get_recipients(%{"type" => "Create"} = data) do
     to = Map.get(data, "to", [])
     cc = Map.get(data, "cc", [])
@@ -85,13 +87,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   defp increase_replies_count_if_reply(_create_data), do: :noop
 
   @object_types ~w[ChatMessage Question Answer Audio Video Event Article]
-  @spec persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
+  @impl true
   def persist(%{"type" => type} = object, meta) when type in @object_types do
     with {:ok, object} <- Object.create(object) do
       {:ok, object, meta}
     end
   end
 
+  @impl true
   def persist(object, meta) do
     with local <- Keyword.fetch!(meta, :local),
          {recipients, _, _} <- get_recipients(object),
diff --git a/lib/pleroma/web/activity_pub/activity_pub/persisting.ex b/lib/pleroma/web/activity_pub/activity_pub/persisting.ex
new file mode 100644
index 000000000..3894f48e2
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/activity_pub/persisting.ex
@@ -0,0 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ActivityPub.Persisting do
+  @callback persist(map(), keyword()) :: {:ok, Activity.t() | Object.t()}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex
index 6e73b2f22..02fdee5fc 100644
--- a/lib/pleroma/web/activity_pub/mrf.ex
+++ b/lib/pleroma/web/activity_pub/mrf.ex
@@ -5,6 +5,8 @@
 defmodule Pleroma.Web.ActivityPub.MRF do
   require Logger
 
+  @behaviour Pleroma.Web.ActivityPub.MRF.PipelineFiltering
+
   @mrf_config_descriptions [
     %{
       group: :pleroma,
@@ -70,6 +72,7 @@ defmodule Pleroma.Web.ActivityPub.MRF do
 
   def filter(%{} = object), do: get_policies() |> filter(object)
 
+  @impl true
   def pipeline_filter(%{} = message, meta) do
     object = meta[:object_data]
     ap_id = message["object"]
diff --git a/lib/pleroma/web/activity_pub/mrf/pipeline_filtering.ex b/lib/pleroma/web/activity_pub/mrf/pipeline_filtering.ex
new file mode 100644
index 000000000..8e0069bc5
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/pipeline_filtering.ex
@@ -0,0 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.PipelineFiltering do
+  @callback pipeline_filter(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
+end
diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex
index bd0a2a8dc..ce8e7341b 100644
--- a/lib/pleroma/web/activity_pub/object_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validator.ex
@@ -9,6 +9,8 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   the system.
   """
 
+  @behaviour Pleroma.Web.ActivityPub.ObjectValidator.Validating
+
   alias Pleroma.Activity
   alias Pleroma.EctoType.ActivityPub.ObjectValidators
   alias Pleroma.Object
@@ -32,7 +34,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.UpdateValidator
 
-  @spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
+  @impl true
   def validate(object, meta)
 
   def validate(%{"type" => type} = object, meta)
diff --git a/lib/pleroma/web/activity_pub/object_validator/validating.ex b/lib/pleroma/web/activity_pub/object_validator/validating.ex
new file mode 100644
index 000000000..64c0c30c5
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/object_validator/validating.ex
@@ -0,0 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ObjectValidator.Validating do
+  @callback validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
+end
diff --git a/lib/pleroma/web/activity_pub/pipeline.ex b/lib/pleroma/web/activity_pub/pipeline.ex
index 98c32a42b..2715b94d4 100644
--- a/lib/pleroma/web/activity_pub/pipeline.ex
+++ b/lib/pleroma/web/activity_pub/pipeline.ex
@@ -14,12 +14,19 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
   alias Pleroma.Web.ActivityPub.Visibility
   alias Pleroma.Web.Federator
 
+  @side_effects Config.get([:pipeline, :side_effects], SideEffects)
+  @federator Config.get([:pipeline, :federator], Federator)
+  @object_validator Config.get([:pipeline, :object_validator], ObjectValidator)
+  @mrf Config.get([:pipeline, :mrf], MRF)
+  @activity_pub Config.get([:pipeline, :activity_pub], ActivityPub)
+  @config Config.get([:pipeline, :config], Config)
+
   @spec common_pipeline(map(), keyword()) ::
           {:ok, Activity.t() | Object.t(), keyword()} | {:error, any()}
   def common_pipeline(object, meta) do
     case Repo.transaction(fn -> do_common_pipeline(object, meta) end) do
       {:ok, {:ok, activity, meta}} ->
-        SideEffects.handle_after_transaction(meta)
+        @side_effects.handle_after_transaction(meta)
         {:ok, activity, meta}
 
       {:ok, value} ->
@@ -35,13 +42,13 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
 
   def do_common_pipeline(object, meta) do
     with {_, {:ok, validated_object, meta}} <-
-           {:validate_object, ObjectValidator.validate(object, meta)},
+           {:validate_object, @object_validator.validate(object, meta)},
          {_, {:ok, mrfd_object, meta}} <-
-           {:mrf_object, MRF.pipeline_filter(validated_object, meta)},
+           {:mrf_object, @mrf.pipeline_filter(validated_object, meta)},
          {_, {:ok, activity, meta}} <-
-           {:persist_object, ActivityPub.persist(mrfd_object, meta)},
+           {:persist_object, @activity_pub.persist(mrfd_object, meta)},
          {_, {:ok, activity, meta}} <-
-           {:execute_side_effects, SideEffects.handle(activity, meta)},
+           {:execute_side_effects, @side_effects.handle(activity, meta)},
          {_, {:ok, _}} <- {:federation, maybe_federate(activity, meta)} do
       {:ok, activity, meta}
     else
@@ -54,7 +61,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
 
   defp maybe_federate(%Activity{} = activity, meta) do
     with {:ok, local} <- Keyword.fetch(meta, :local) do
-      do_not_federate = meta[:do_not_federate] || !Config.get([:instance, :federating])
+      do_not_federate = meta[:do_not_federate] || !@config.get([:instance, :federating])
 
       if !do_not_federate and local and not Visibility.is_local_public?(activity) do
         activity =
@@ -64,7 +71,7 @@ defmodule Pleroma.Web.ActivityPub.Pipeline do
             activity
           end
 
-        Federator.publish(activity)
+        @federator.publish(activity)
         {:ok, :federated}
       else
         {:ok, :not_federated}
diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex
index 8556fca1d..55c99ad0c 100644
--- a/lib/pleroma/web/activity_pub/side_effects.ex
+++ b/lib/pleroma/web/activity_pub/side_effects.ex
@@ -27,11 +27,17 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
 
   require Logger
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
+  @behaviour Pleroma.Web.ActivityPub.SideEffects.Handling
+
+  @impl true
   def handle(object, meta \\ [])
 
   # Task this handles
   # - Follows
   # - Sends a notification
+  @impl true
   def handle(
         %{
           data: %{
@@ -59,6 +65,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # - Rejects all existing follow activities for this person
   # - Updates the follow state
   # - Dismisses notification
+  @impl true
   def handle(
         %{
           data: %{
@@ -85,6 +92,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # - Follows if possible
   # - Sends a notification
   # - Generates accept or reject if appropriate
+  @impl true
   def handle(
         %{
           data: %{
@@ -126,6 +134,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
 
   # Tasks this handles:
   # - Unfollow and block
+  @impl true
   def handle(
         %{data: %{"type" => "Block", "object" => blocked_user, "actor" => blocking_user}} =
           object,
@@ -144,6 +153,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   #
   # For a local user, we also get a changeset with the full information, so we
   # can update non-federating, non-activitypub settings as well.
+  @impl true
   def handle(%{data: %{"type" => "Update", "object" => updated_object}} = object, meta) do
     if changeset = Keyword.get(meta, :user_update_changeset) do
       changeset
@@ -162,6 +172,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # Tasks this handles:
   # - Add like to object
   # - Set up notification
+  @impl true
   def handle(%{data: %{"type" => "Like"}} = object, meta) do
     liked_object = Object.get_by_ap_id(object.data["object"])
     Utils.add_like_to_object(object, liked_object)
@@ -179,6 +190,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # - Increase replies count
   # - Set up ActivityExpiration
   # - Set up notifications
+  @impl true
   def handle(%{data: %{"type" => "Create"}} = activity, meta) do
     with {:ok, object, meta} <- handle_object_creation(meta[:object_data], meta),
          %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
@@ -207,6 +219,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # - Add announce to object
   # - Set up notification
   # - Stream out the announce
+  @impl true
   def handle(%{data: %{"type" => "Announce"}} = object, meta) do
     announced_object = Object.get_by_ap_id(object.data["object"])
     user = User.get_cached_by_ap_id(object.data["actor"])
@@ -224,6 +237,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
     {:ok, object, meta}
   end
 
+  @impl true
   def handle(%{data: %{"type" => "Undo", "object" => undone_object}} = object, meta) do
     with undone_object <- Activity.get_by_ap_id(undone_object),
          :ok <- handle_undoing(undone_object) do
@@ -234,6 +248,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # Tasks this handles:
   # - Add reaction to object
   # - Set up notification
+  @impl true
   def handle(%{data: %{"type" => "EmojiReact"}} = object, meta) do
     reacted_object = Object.get_by_ap_id(object.data["object"])
     Utils.add_emoji_reaction_to_object(object, reacted_object)
@@ -250,6 +265,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   # - Reduce the user note count
   # - Reduce the reply count
   # - Stream out the activity
+  @impl true
   def handle(%{data: %{"type" => "Delete", "object" => deleted_object}} = object, meta) do
     deleted_object =
       Object.normalize(deleted_object, false) ||
@@ -295,6 +311,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   end
 
   # Nothing to do
+  @impl true
   def handle(object, meta) do
     {:ok, object, meta}
   end
@@ -312,7 +329,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
             {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
             {:ok, cm_ref} = MessageReference.create(chat, object, user.ap_id != actor.ap_id)
 
-            Cachex.put(
+            @cachex.put(
               :chat_message_id_idempotency_key_cache,
               cm_ref.id,
               meta[:idempotency_key]
@@ -439,6 +456,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
     |> Keyword.put(:notifications, notifications ++ existing)
   end
 
+  @impl true
   def handle_after_transaction(meta) do
     meta
     |> send_notifications()
diff --git a/lib/pleroma/web/activity_pub/side_effects/handling.ex b/lib/pleroma/web/activity_pub/side_effects/handling.ex
new file mode 100644
index 000000000..9d64c0e47
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/side_effects/handling.ex
@@ -0,0 +1,8 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.SideEffects.Handling do
+  @callback handle(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
+  @callback handle_after_transaction(map()) :: map()
+end
diff --git a/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex b/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
index 6d92e9f7f..2f712fb8c 100644
--- a/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex
@@ -9,6 +9,8 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
   alias Pleroma.Web.MediaProxy
   alias Pleroma.Web.Plugs.OAuthScopesPlug
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   plug(Pleroma.Web.ApiSpec.CastAndValidate)
 
   plug(
@@ -38,7 +40,7 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheController do
 
   defp fetch_entries(params) do
     MediaProxy.cache_table()
-    |> Cachex.stream!(Cachex.Query.create(true, :key))
+    |> @cachex.stream!(Cachex.Query.create(true, :key))
     |> filter_entries(params[:query])
   end
 
diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex
index 130654145..658d20954 100644
--- a/lib/pleroma/web/federator.ex
+++ b/lib/pleroma/web/federator.ex
@@ -15,6 +15,8 @@ defmodule Pleroma.Web.Federator do
 
   require Logger
 
+  @behaviour Pleroma.Web.Federator.Publishing
+
   @doc """
   Returns `true` if the distance to target object does not exceed max configured value.
   Serves to prevent fetching of very long threads, especially useful on smaller instances.
@@ -39,10 +41,12 @@ defmodule Pleroma.Web.Federator do
     ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params})
   end
 
+  @impl true
   def publish(%{id: "pleroma:fakeid"} = activity) do
     perform(:publish, activity)
   end
 
+  @impl true
   def publish(activity) do
     PublisherWorker.enqueue("publish", %{"activity_id" => activity.id})
   end
diff --git a/lib/jason_types.ex b/lib/pleroma/web/federator/publishing.ex
similarity index 59%
rename from lib/jason_types.ex
rename to lib/pleroma/web/federator/publishing.ex
index f1fdc96f4..d6fba8f24 100644
--- a/lib/jason_types.ex
+++ b/lib/pleroma/web/federator/publishing.ex
@@ -2,8 +2,6 @@
 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
-Postgrex.Types.define(
-  Pleroma.PostgresTypes,
-  [] ++ Ecto.Adapters.Postgres.extensions(),
-  json: Jason
-)
+defmodule Pleroma.Web.Federator.Publishing do
+  @callback publish(map()) :: any()
+end
diff --git a/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex b/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
index 3dcd1c44f..e26ec7136 100644
--- a/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/poll_controller.ex
@@ -26,6 +26,8 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
 
   defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PollOperation
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   @doc "GET /api/v1/polls/:id"
   def show(%{assigns: %{user: user}} = conn, %{id: id}) do
     with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60),
@@ -55,7 +57,7 @@ defmodule Pleroma.Web.MastodonAPI.PollController do
   defp get_cached_vote_or_vote(user, object, choices) do
     idempotency_key = "polls:#{user.id}:#{object.data["id"]}"
 
-    Cachex.fetch!(:idempotency_cache, idempotency_key, fn ->
+    @cachex.fetch!(:idempotency_cache, idempotency_key, fn _ ->
       case CommonAPI.vote(user, object, choices) do
         {:error, _message} = res -> {:ignore, res}
         res -> {:commit, res}
diff --git a/lib/pleroma/web/media_proxy.ex b/lib/pleroma/web/media_proxy.ex
index 8656b8cad..2793cabc1 100644
--- a/lib/pleroma/web/media_proxy.ex
+++ b/lib/pleroma/web/media_proxy.ex
@@ -12,29 +12,31 @@ defmodule Pleroma.Web.MediaProxy do
   @base64_opts [padding: false]
   @cache_table :banned_urls_cache
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   def cache_table, do: @cache_table
 
   @spec in_banned_urls(String.t()) :: boolean()
-  def in_banned_urls(url), do: elem(Cachex.exists?(@cache_table, url(url)), 1)
+  def in_banned_urls(url), do: elem(@cachex.exists?(@cache_table, url(url)), 1)
 
   def remove_from_banned_urls(urls) when is_list(urls) do
-    Cachex.execute!(@cache_table, fn cache ->
-      Enum.each(Invalidation.prepare_urls(urls), &Cachex.del(cache, &1))
+    @cachex.execute!(@cache_table, fn cache ->
+      Enum.each(Invalidation.prepare_urls(urls), &@cachex.del(cache, &1))
     end)
   end
 
   def remove_from_banned_urls(url) when is_binary(url) do
-    Cachex.del(@cache_table, url(url))
+    @cachex.del(@cache_table, url(url))
   end
 
   def put_in_banned_urls(urls) when is_list(urls) do
-    Cachex.execute!(@cache_table, fn cache ->
-      Enum.each(Invalidation.prepare_urls(urls), &Cachex.put(cache, &1, true))
+    @cachex.execute!(@cache_table, fn cache ->
+      Enum.each(Invalidation.prepare_urls(urls), &@cachex.put(cache, &1, true))
     end)
   end
 
   def put_in_banned_urls(url) when is_binary(url) do
-    Cachex.put(@cache_table, url(url), true)
+    @cachex.put(@cache_table, url(url), true)
   end
 
   def url(url) when is_nil(url) or url == "", do: nil
diff --git a/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex b/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex
index c058fb340..df48044e3 100644
--- a/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex
+++ b/lib/pleroma/web/pleroma_api/views/chat/message_reference_view.ex
@@ -10,6 +10,8 @@ defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceView do
   alias Pleroma.Web.CommonAPI.Utils
   alias Pleroma.Web.MastodonAPI.StatusView
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   def render(
         "show.json",
         %{
@@ -51,7 +53,7 @@ defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceView do
   end
 
   defp put_idempotency_key(data) do
-    with {:ok, idempotency_key} <- Cachex.get(:chat_message_id_idempotency_key_cache, data.id) do
+    with {:ok, idempotency_key} <- @cachex.get(:chat_message_id_idempotency_key_cache, data.id) do
       data
       |> Maps.put_if_present(:idempotency_key, idempotency_key)
     else
diff --git a/lib/pleroma/web/plugs/cache.ex b/lib/pleroma/web/plugs/cache.ex
index 6de01804a..18880716a 100644
--- a/lib/pleroma/web/plugs/cache.ex
+++ b/lib/pleroma/web/plugs/cache.ex
@@ -41,6 +41,8 @@ defmodule Pleroma.Web.Plugs.Cache do
 
   @defaults %{ttl: nil, query_params: true}
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   @impl true
   def init([]), do: @defaults
 
@@ -53,7 +55,7 @@ defmodule Pleroma.Web.Plugs.Cache do
   def call(%{method: "GET"} = conn, opts) do
     key = cache_key(conn, opts)
 
-    case Cachex.get(:web_resp_cache, key) do
+    case @cachex.get(:web_resp_cache, key) do
       {:ok, nil} ->
         cache_resp(conn, opts)
 
@@ -97,11 +99,11 @@ defmodule Pleroma.Web.Plugs.Cache do
 
         conn =
           unless opts[:tracking_fun] do
-            Cachex.put(:web_resp_cache, key, {content_type, body}, ttl: ttl)
+            @cachex.put(:web_resp_cache, key, {content_type, body}, ttl: ttl)
             conn
           else
             tracking_fun_data = Map.get(conn.assigns, :tracking_fun_data, nil)
-            Cachex.put(:web_resp_cache, key, {content_type, body, tracking_fun_data}, ttl: ttl)
+            @cachex.put(:web_resp_cache, key, {content_type, body, tracking_fun_data}, ttl: ttl)
 
             opts.tracking_fun.(conn, tracking_fun_data)
           end
diff --git a/lib/pleroma/web/plugs/idempotency_plug.ex b/lib/pleroma/web/plugs/idempotency_plug.ex
index 254a790b0..4f908779c 100644
--- a/lib/pleroma/web/plugs/idempotency_plug.ex
+++ b/lib/pleroma/web/plugs/idempotency_plug.ex
@@ -8,6 +8,8 @@ defmodule Pleroma.Web.Plugs.IdempotencyPlug do
 
   @behaviour Plug
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   @impl true
   def init(opts), do: opts
 
@@ -25,7 +27,7 @@ defmodule Pleroma.Web.Plugs.IdempotencyPlug do
   def call(conn, _), do: conn
 
   def process_request(conn, key) do
-    case Cachex.get(:idempotency_cache, key) do
+    case @cachex.get(:idempotency_cache, key) do
       {:ok, nil} ->
         cache_resposnse(conn, key)
 
@@ -43,7 +45,7 @@ defmodule Pleroma.Web.Plugs.IdempotencyPlug do
       content_type = get_content_type(conn)
 
       record = {request_id, content_type, conn.status, conn.resp_body}
-      {:ok, _} = Cachex.put(:idempotency_cache, key, record)
+      {:ok, _} = @cachex.put(:idempotency_cache, key, record)
 
       conn
       |> put_resp_header("idempotency-key", key)
diff --git a/lib/pleroma/web/plugs/rate_limiter.ex b/lib/pleroma/web/plugs/rate_limiter.ex
index a589610d1..034a5bbe2 100644
--- a/lib/pleroma/web/plugs/rate_limiter.ex
+++ b/lib/pleroma/web/plugs/rate_limiter.ex
@@ -72,6 +72,8 @@ defmodule Pleroma.Web.Plugs.RateLimiter do
 
   require Logger
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   @doc false
   def init(plug_opts) do
     plug_opts
@@ -124,7 +126,7 @@ defmodule Pleroma.Web.Plugs.RateLimiter do
       key_name = make_key_name(action_settings)
       limit = get_limits(action_settings)
 
-      case Cachex.get(bucket_name, key_name) do
+      case @cachex.get(bucket_name, key_name) do
         {:error, :no_cache} ->
           @inspect_bucket_not_found
 
@@ -157,7 +159,7 @@ defmodule Pleroma.Web.Plugs.RateLimiter do
     key_name = make_key_name(action_settings)
     limit = get_limits(action_settings)
 
-    case Cachex.get_and_update(bucket_name, key_name, &increment_value(&1, limit)) do
+    case @cachex.get_and_update(bucket_name, key_name, &increment_value(&1, limit)) do
       {:commit, value} ->
         {:ok, value}
 
diff --git a/lib/pleroma/web/rel_me.ex b/lib/pleroma/web/rel_me.ex
index 28f75b18d..650c6a3fc 100644
--- a/lib/pleroma/web/rel_me.ex
+++ b/lib/pleroma/web/rel_me.ex
@@ -12,8 +12,9 @@ defmodule Pleroma.Web.RelMe do
   if Pleroma.Config.get(:env) == :test do
     def parse(url) when is_binary(url), do: parse_url(url)
   else
+    @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
     def parse(url) when is_binary(url) do
-      Cachex.fetch!(:rel_me_cache, url, fn _ ->
+      @cachex.fetch!(:rel_me_cache, url, fn _ ->
         {:commit, parse_url(url)}
       end)
     rescue
diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex
index c70d2fdba..d7a491198 100644
--- a/lib/pleroma/web/rich_media/parser.ex
+++ b/lib/pleroma/web/rich_media/parser.ex
@@ -5,6 +5,8 @@
 defmodule Pleroma.Web.RichMedia.Parser do
   require Logger
 
+  @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+
   defp parsers do
     Pleroma.Config.get([:rich_media, :parsers])
   end
@@ -24,7 +26,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
     end
 
     defp get_cached_or_parse(url) do
-      case Cachex.fetch(:rich_media_cache, url, fn ->
+      case @cachex.fetch(:rich_media_cache, url, fn ->
              case parse_url(url) do
                {:ok, _} = res ->
                  {:commit, res}
@@ -64,7 +66,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
 
     defp set_error_ttl(url, _reason) do
       ttl = Pleroma.Config.get([:rich_media, :failure_backoff], 60_000)
-      Cachex.expire(:rich_media_cache, url, ttl)
+      @cachex.expire(:rich_media_cache, url, ttl)
       :ok
     end
 
@@ -106,7 +108,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
       {:ok, ttl} when is_number(ttl) ->
         ttl = ttl * 1000
 
-        case Cachex.expire_at(:rich_media_cache, url, ttl) do
+        case @cachex.expire_at(:rich_media_cache, url, ttl) do
           {:ok, true} -> {:ok, ttl}
           {:ok, false} -> {:error, :no_key}
         end
diff --git a/mix.exs b/mix.exs
index fb5b380f4..a596e34ea 100644
--- a/mix.exs
+++ b/mix.exs
@@ -158,7 +158,7 @@ defmodule Pleroma.Mixfile do
       {:floki, "~> 0.27"},
       {:timex, "~> 3.6"},
       {:ueberauth, "~> 0.4"},
-      {:linkify, "~> 0.4.0"},
+      {:linkify, "~> 0.4.1"},
       {:http_signatures, "~> 0.1.0"},
       {:telemetry, "~> 0.3"},
       {:poolboy, "~> 1.5"},
@@ -211,7 +211,7 @@ defmodule Pleroma.Mixfile do
        git: "https://git.pleroma.social/pleroma/elixir-libraries/hackney.git",
        ref: "7d7119f0651515d6d7669c78393fd90950a3ec6e",
        override: true},
-      {:mox, "~> 0.5", only: :test},
+      {:mox, "~> 1.0", only: :test},
       {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test}
     ] ++ oauth_deps()
   end
diff --git a/mix.lock b/mix.lock
index 7db71453f..32b2e1391 100644
--- a/mix.lock
+++ b/mix.lock
@@ -33,7 +33,7 @@
   "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
   "ecto_sql": {:hex, :ecto_sql, "3.4.5", "30161f81b167d561a9a2df4329c10ae05ff36eca7ccc84628f2c8b9fa1e43323", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "31990c6a3579b36a3c0841d34a94c275e727de8b84f58509da5f1b2032c98ac2"},
   "eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"},
-  "elixir_make": {:hex, :elixir_make, "0.6.1", "8faa29a5597faba999aeeb72bbb9c91694ef8068f0131192fb199f98d32994ef", [:mix], [], "hexpm", "35d33270680f8d839a4003c3e9f43afb595310a592405a00afc12de4c7f55a18"},
+  "elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
   "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"},
   "eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"},
   "ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"},
@@ -65,7 +65,7 @@
   "jose": {:hex, :jose, "1.10.1", "16d8e460dae7203c6d1efa3f277e25b5af8b659febfc2f2eb4bacf87f128b80a", [:mix, :rebar3], [], "hexpm", "3c7ddc8a9394b92891db7c2771da94bf819834a1a4c92e30857b7d582e2f8257"},
   "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
   "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
-  "linkify": {:hex, :linkify, "0.4.0", "7845b6ac33050a41acaf9318923ce6e7f3854418be9a5f22184de103f7a68ff9", [:mix], [], "hexpm", "a0ceb4c78591fecccf1d99fecc10c13dba75a307c663c80e28af9e2cdd9776ee"},
+  "linkify": {:hex, :linkify, "0.4.1", "f881eb3429ae88010cf736e6fb3eed406c187bcdd544902ec937496636b7c7b3", [:mix], [], "hexpm", "ce98693f54ae9ace59f2f7a8aed3de2ef311381a8ce7794804bd75484c371dda"},
   "majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "4c692e544b28d1f5e543fb8a44be090f8cd96f80", [ref: "4c692e544b28d1f5e543fb8a44be090f8cd96f80"]},
   "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
   "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
@@ -76,7 +76,7 @@
   "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
   "mock": {:hex, :mock, "0.3.5", "feb81f52b8dcf0a0d65001d2fec459f6b6a8c22562d94a965862f6cc066b5431", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "6fae404799408300f863550392635d8f7e3da6b71abdd5c393faf41b131c8728"},
   "mogrify": {:hex, :mogrify, "0.7.4", "9b2496dde44b1ce12676f85d7dc531900939e6367bc537c7243a1b089435b32d", [:mix], [], "hexpm", "50d79e337fba6bc95bfbef918058c90f50b17eed9537771e61d4619488f099c3"},
-  "mox": {:hex, :mox, "0.5.2", "55a0a5ba9ccc671518d068c8dddd20eeb436909ea79d1799e2209df7eaa98b6c", [:mix], [], "hexpm", "df4310628cd628ee181df93f50ddfd07be3e5ecc30232d3b6aadf30bdfe6092b"},
+  "mox": {:hex, :mox, "1.0.0", "4b3c7005173f47ff30641ba044eb0fe67287743eec9bd9545e37f3002b0a9f8b", [:mix], [], "hexpm", "201b0a20b7abdaaab083e9cf97884950f8a30a1350a1da403b3145e213c6f4df"},
   "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
   "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
   "nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
diff --git a/priv/templates/sample_config.eex b/priv/templates/sample_config.eex
index cdddc47ea..2f5952ef1 100644
--- a/priv/templates/sample_config.eex
+++ b/priv/templates/sample_config.eex
@@ -32,8 +32,7 @@ config :pleroma, Pleroma.Repo,
   username: "<%= dbuser %>",
   password: "<%= dbpass %>",
   database: "<%= dbname %>",
-  hostname: "<%= dbhost %>",
-  pool_size: 10
+  hostname: "<%= dbhost %>"
 
 # Configure web push notifications
 config :web_push_encryption, :vapid_details,
diff --git a/test/mix/tasks/pleroma/count_statuses_test.exs b/test/mix/tasks/pleroma/count_statuses_test.exs
index c5cd16960..8fe3959ea 100644
--- a/test/mix/tasks/pleroma/count_statuses_test.exs
+++ b/test/mix/tasks/pleroma/count_statuses_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.CountStatusesTest do
+  # Uses log capture, has to stay synchronous
   use Pleroma.DataCase
 
   alias Pleroma.User
diff --git a/test/mix/tasks/pleroma/database_test.exs b/test/mix/tasks/pleroma/database_test.exs
index cf28576b5..eefb12426 100644
--- a/test/mix/tasks/pleroma/database_test.exs
+++ b/test/mix/tasks/pleroma/database_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.DatabaseTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   use Oban.Testing, repo: Pleroma.Repo
 
   alias Pleroma.Activity
diff --git a/test/mix/tasks/pleroma/ecto/migrate_test.exs b/test/mix/tasks/pleroma/ecto/migrate_test.exs
index 43df176a1..548357508 100644
--- a/test/mix/tasks/pleroma/ecto/migrate_test.exs
+++ b/test/mix/tasks/pleroma/ecto/migrate_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-onl
 
 defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do
-  use Pleroma.DataCase, async: true
+  use Pleroma.DataCase
   import ExUnit.CaptureLog
   require Logger
 
diff --git a/test/mix/tasks/pleroma/ecto/rollback_test.exs b/test/mix/tasks/pleroma/ecto/rollback_test.exs
index 0236e35d5..9e39db8fa 100644
--- a/test/mix/tasks/pleroma/ecto/rollback_test.exs
+++ b/test/mix/tasks/pleroma/ecto/rollback_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.Ecto.RollbackTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import ExUnit.CaptureLog
   require Logger
 
diff --git a/test/mix/tasks/pleroma/instance_test.exs b/test/mix/tasks/pleroma/instance_test.exs
index 6580fc932..1d2dde108 100644
--- a/test/mix/tasks/pleroma/instance_test.exs
+++ b/test/mix/tasks/pleroma/instance_test.exs
@@ -3,7 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.InstanceTest do
-  use ExUnit.Case
+  # Modifies the Application Environment, has to stay synchronous.
+  use Pleroma.DataCase
 
   setup do
     File.mkdir_p!(tmp_path())
@@ -15,15 +16,17 @@ defmodule Mix.Tasks.Pleroma.InstanceTest do
       if File.exists?(static_dir) do
         File.rm_rf(Path.join(static_dir, "robots.txt"))
       end
-
-      Pleroma.Config.put([:instance, :static_dir], static_dir)
     end)
 
+    # Is being modified by the mix task.
+    clear_config([:instance, :static_dir])
+
     :ok
   end
 
+  @uuid Ecto.UUID.generate()
   defp tmp_path do
-    "/tmp/generated_files/"
+    "/tmp/generated_files/#{@uuid}/"
   end
 
   test "running gen" do
diff --git a/test/mix/tasks/pleroma/refresh_counter_cache_test.exs b/test/mix/tasks/pleroma/refresh_counter_cache_test.exs
index 6a1a9ac17..e79dc0632 100644
--- a/test/mix/tasks/pleroma/refresh_counter_cache_test.exs
+++ b/test/mix/tasks/pleroma/refresh_counter_cache_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.RefreshCounterCacheTest do
+  # Uses log capture, has to stay synchronous
   use Pleroma.DataCase
   alias Pleroma.Web.CommonAPI
   import ExUnit.CaptureIO, only: [capture_io: 1]
diff --git a/test/mix/tasks/pleroma/relay_test.exs b/test/mix/tasks/pleroma/relay_test.exs
index cf48e7dda..b453ed1c6 100644
--- a/test/mix/tasks/pleroma/relay_test.exs
+++ b/test/mix/tasks/pleroma/relay_test.exs
@@ -100,7 +100,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
       end)
 
       Pleroma.Repo.delete(user)
-      Cachex.clear(:user_cache)
+      User.invalidate_cache(user)
 
       Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance])
 
@@ -137,7 +137,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
       end)
 
       Pleroma.Repo.delete(user)
-      Cachex.clear(:user_cache)
+      User.invalidate_cache(user)
 
       Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance, "--force"])
 
diff --git a/test/pleroma/activity/ir/topics_test.exs b/test/pleroma/activity/ir/topics_test.exs
index 5e5c2f8da..b464822d9 100644
--- a/test/pleroma/activity/ir/topics_test.exs
+++ b/test/pleroma/activity/ir/topics_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Activity.Ir.TopicsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Activity.Ir.Topics
diff --git a/test/pleroma/activity/search_test.exs b/test/pleroma/activity/search_test.exs
index fc910e725..49b7aa292 100644
--- a/test/pleroma/activity/search_test.exs
+++ b/test/pleroma/activity/search_test.exs
@@ -7,7 +7,7 @@ defmodule Pleroma.Activity.SearchTest do
   alias Pleroma.Web.CommonAPI
   import Pleroma.Factory
 
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   test "it finds something" do
     user = insert(:user)
diff --git a/test/pleroma/application_requirements_test.exs b/test/pleroma/application_requirements_test.exs
index b432dbc37..e3cca5487 100644
--- a/test/pleroma/application_requirements_test.exs
+++ b/test/pleroma/application_requirements_test.exs
@@ -15,6 +15,7 @@ defmodule Pleroma.ApplicationRequirementsTest do
   describe "check_repo_pool_size!/1" do
     test "raises if the pool size is unexpected" do
       clear_config([Pleroma.Repo, :pool_size], 11)
+      clear_config([:dangerzone, :override_repo_pool_size], false)
 
       assert_raise Pleroma.ApplicationRequirements.VerifyError,
                    "Repo.pool_size different than recommended value.",
diff --git a/test/pleroma/bbs/handler_test.exs b/test/pleroma/bbs/handler_test.exs
index e605c2726..bba8fab0f 100644
--- a/test/pleroma/bbs/handler_test.exs
+++ b/test/pleroma/bbs/handler_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.BBS.HandlerTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Activity
   alias Pleroma.BBS.Handler
   alias Pleroma.Object
diff --git a/test/pleroma/bookmark_test.exs b/test/pleroma/bookmark_test.exs
index 2726fe7cd..ef090d785 100644
--- a/test/pleroma/bookmark_test.exs
+++ b/test/pleroma/bookmark_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.BookmarkTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Bookmark
   alias Pleroma.Web.CommonAPI
diff --git a/test/pleroma/captcha_test.exs b/test/pleroma/captcha_test.exs
index 1b9f4a12f..bde3c72f7 100644
--- a/test/pleroma/captcha_test.exs
+++ b/test/pleroma/captcha_test.exs
@@ -80,7 +80,6 @@ defmodule Pleroma.CaptchaTest do
 
       assert is_binary(answer)
       assert :ok = Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer)
-      Cachex.del(:used_captcha_cache, token)
     end
 
     test "doesn't validate invalid answer" do
diff --git a/test/pleroma/chat_test.exs b/test/pleroma/chat_test.exs
index 9e8a9ebf0..1dd04916c 100644
--- a/test/pleroma/chat_test.exs
+++ b/test/pleroma/chat_test.exs
@@ -73,7 +73,8 @@ defmodule Pleroma.ChatTest do
       other_user = insert(:user)
 
       {:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
-      :timer.sleep(1500)
+      {:ok, chat} = time_travel(chat, -2)
+
       {:ok, chat_two} = Chat.bump_or_create(user.id, other_user.ap_id)
 
       assert chat.id == chat_two.id
diff --git a/test/pleroma/config_test.exs b/test/pleroma/config_test.exs
index 1556e4237..f524d90dd 100644
--- a/test/pleroma/config_test.exs
+++ b/test/pleroma/config_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.ConfigTest do
-  use ExUnit.Case
+  use Pleroma.DataCase
 
   test "get/1 with an atom" do
     assert Pleroma.Config.get(:instance) == Application.get_env(:pleroma, :instance)
diff --git a/test/pleroma/conversation/participation_test.exs b/test/pleroma/conversation/participation_test.exs
index 5a603dcc1..122b10486 100644
--- a/test/pleroma/conversation/participation_test.exs
+++ b/test/pleroma/conversation/participation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Conversation.ParticipationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Conversation
   alias Pleroma.Conversation.Participation
@@ -96,12 +96,11 @@ defmodule Pleroma.Conversation.ParticipationTest do
     {:ok, %Participation{} = participation} =
       Participation.create_for_user_and_conversation(user, conversation)
 
+    {:ok, participation} = time_travel(participation, -2)
+
     assert participation.user_id == user.id
     assert participation.conversation_id == conversation.id
 
-    # Needed because updated_at is accurate down to a second
-    :timer.sleep(1000)
-
     # Creating again returns the same participation
     {:ok, %Participation{} = participation_two} =
       Participation.create_for_user_and_conversation(user, conversation)
diff --git a/test/pleroma/earmark_renderer_test.exs b/test/pleroma/earmark_renderer_test.exs
index 220d97d16..73aaec7f4 100644
--- a/test/pleroma/earmark_renderer_test.exs
+++ b/test/pleroma/earmark_renderer_test.exs
@@ -2,7 +2,7 @@
 # Copyright © 2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 defmodule Pleroma.EarmarkRendererTest do
-  use ExUnit.Case
+  use Pleroma.DataCase, async: true
 
   test "Paragraph" do
     code = ~s[Hello\n\nWorld!]
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs
index 812463454..a8471e2e3 100644
--- a/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/date_time_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.DateTimeTest do
   alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   test "it validates an xsd:Datetime" do
     valid_strings = [
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs
index 732e2365f..3b6006854 100644
--- a/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/object_id_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectIDTest do
   alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   @uris [
     "http://lain.com/users/lain",
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs
index 2e6a0c83d..b7eb59ab0 100644
--- a/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/recipients_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.RecipientsTest do
   alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   test "it asserts that all elements of the list are object ids" do
     list = ["https://lain.com/users/lain", "invalid"]
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs
index 7eddd2388..154363f68 100644
--- a/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/safe_text_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.SafeTextTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
 
diff --git a/test/pleroma/emails/admin_email_test.exs b/test/pleroma/emails/admin_email_test.exs
index 0da0699cc..9aaf7b04f 100644
--- a/test/pleroma/emails/admin_email_test.exs
+++ b/test/pleroma/emails/admin_email_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Emails.AdminEmailTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.Emails.AdminEmail
diff --git a/test/pleroma/emails/user_email_test.exs b/test/pleroma/emails/user_email_test.exs
index a214e59a7..bd21d8dec 100644
--- a/test/pleroma/emails/user_email_test.exs
+++ b/test/pleroma/emails/user_email_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Emails.UserEmailTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Emails.UserEmail
   alias Pleroma.Web.Endpoint
diff --git a/test/pleroma/emoji/formatter_test.exs b/test/pleroma/emoji/formatter_test.exs
index 12af6cd8b..096d23ca6 100644
--- a/test/pleroma/emoji/formatter_test.exs
+++ b/test/pleroma/emoji/formatter_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.Emoji.FormatterTest do
   alias Pleroma.Emoji.Formatter
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   describe "emojify" do
     test "it adds cool emoji" do
diff --git a/test/pleroma/emoji/pack_test.exs b/test/pleroma/emoji/pack_test.exs
index 70d1eaa1b..158dfee06 100644
--- a/test/pleroma/emoji/pack_test.exs
+++ b/test/pleroma/emoji/pack_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Emoji.PackTest do
-  use ExUnit.Case, async: true
+  use Pleroma.DataCase
   alias Pleroma.Emoji.Pack
 
   @emoji_path Path.join(
diff --git a/test/pleroma/emoji_test.exs b/test/pleroma/emoji_test.exs
index 9cfd7b46b..c99c9ef4c 100644
--- a/test/pleroma/emoji_test.exs
+++ b/test/pleroma/emoji_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.EmojiTest do
-  use ExUnit.Case
+  use ExUnit.Case, async: true
   alias Pleroma.Emoji
 
   describe "is_unicode_emoji?/1" do
diff --git a/test/pleroma/filter_test.exs b/test/pleroma/filter_test.exs
index 0a5c4426a..da9515902 100644
--- a/test/pleroma/filter_test.exs
+++ b/test/pleroma/filter_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.FilterTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/following_relationship_test.exs b/test/pleroma/following_relationship_test.exs
index 17a468abb..f0d2c3846 100644
--- a/test/pleroma/following_relationship_test.exs
+++ b/test/pleroma/following_relationship_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.FollowingRelationshipTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.FollowingRelationship
   alias Pleroma.Web.ActivityPub.InternalFetchActor
diff --git a/test/pleroma/healthcheck_test.exs b/test/pleroma/healthcheck_test.exs
index e341e6983..a1bc25d25 100644
--- a/test/pleroma/healthcheck_test.exs
+++ b/test/pleroma/healthcheck_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.HealthcheckTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Healthcheck
 
   test "system_info/0" do
diff --git a/test/pleroma/html_test.exs b/test/pleroma/html_test.exs
index 7d3756884..9737f2458 100644
--- a/test/pleroma/html_test.exs
+++ b/test/pleroma/html_test.exs
@@ -6,7 +6,7 @@ defmodule Pleroma.HTMLTest do
   alias Pleroma.HTML
   alias Pleroma.Object
   alias Pleroma.Web.CommonAPI
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/http/adapter_helper/gun_test.exs b/test/pleroma/http/adapter_helper/gun_test.exs
index 80589c73d..487d2e7c1 100644
--- a/test/pleroma/http/adapter_helper/gun_test.exs
+++ b/test/pleroma/http/adapter_helper/gun_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.HTTP.AdapterHelper.GunTest do
-  use ExUnit.Case, async: true
+  use ExUnit.Case
   use Pleroma.Tests.Helpers
 
   import Mox
diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs
index bb8e795b7..4a7dbda71 100644
--- a/test/pleroma/integration/mastodon_websocket_test.exs
+++ b/test/pleroma/integration/mastodon_websocket_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Integration.MastodonWebsocketTest do
+  # Needs a streamer, needs to stay synchronous
   use Pleroma.DataCase
 
   import ExUnit.CaptureLog
diff --git a/test/pleroma/keys_test.exs b/test/pleroma/keys_test.exs
index 9e8528cba..55a7aa1bc 100644
--- a/test/pleroma/keys_test.exs
+++ b/test/pleroma/keys_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.KeysTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Keys
 
diff --git a/test/pleroma/list_test.exs b/test/pleroma/list_test.exs
index b5572cbae..854e276f1 100644
--- a/test/pleroma/list_test.exs
+++ b/test/pleroma/list_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.ListTest do
   alias Pleroma.Repo
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/marker_test.exs b/test/pleroma/marker_test.exs
index 7b3943c7b..3055f1ce2 100644
--- a/test/pleroma/marker_test.exs
+++ b/test/pleroma/marker_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.MarkerTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Marker
 
   import Pleroma.Factory
diff --git a/test/pleroma/mfa/backup_codes_test.exs b/test/pleroma/mfa/backup_codes_test.exs
index 41adb1e96..c3eaf40b6 100644
--- a/test/pleroma/mfa/backup_codes_test.exs
+++ b/test/pleroma/mfa/backup_codes_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.MFA.BackupCodesTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.MFA.BackupCodes
 
diff --git a/test/pleroma/mfa/totp_test.exs b/test/pleroma/mfa/totp_test.exs
index 9edb6fd54..8c09bf447 100644
--- a/test/pleroma/mfa/totp_test.exs
+++ b/test/pleroma/mfa/totp_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.MFA.TOTPTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.MFA.TOTP
 
diff --git a/test/pleroma/mfa_test.exs b/test/pleroma/mfa_test.exs
index 8875cefd9..cd1f7d0af 100644
--- a/test/pleroma/mfa_test.exs
+++ b/test/pleroma/mfa_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.MFATest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
   alias Pleroma.MFA
diff --git a/test/pleroma/migration_helper/notification_backfill_test.exs b/test/pleroma/migration_helper/notification_backfill_test.exs
index 2a62a2b00..6fe8a11ac 100644
--- a/test/pleroma/migration_helper/notification_backfill_test.exs
+++ b/test/pleroma/migration_helper/notification_backfill_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.MigrationHelper.NotificationBackfillTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.MigrationHelper.NotificationBackfill
diff --git a/test/pleroma/moderation_log_test.exs b/test/pleroma/moderation_log_test.exs
index 03b32a060..d1e0e1e6b 100644
--- a/test/pleroma/moderation_log_test.exs
+++ b/test/pleroma/moderation_log_test.exs
@@ -6,7 +6,7 @@ defmodule Pleroma.ModerationLogTest do
   alias Pleroma.Activity
   alias Pleroma.ModerationLog
 
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/pagination_test.exs b/test/pleroma/pagination_test.exs
index e526f23e8..5ee1e60ae 100644
--- a/test/pleroma/pagination_test.exs
+++ b/test/pleroma/pagination_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.PaginationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/registration_test.exs b/test/pleroma/registration_test.exs
index 7db8e3664..462ab452b 100644
--- a/test/pleroma/registration_test.exs
+++ b/test/pleroma/registration_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.RegistrationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/repo/migrations/fix_legacy_tags_test.exs b/test/pleroma/repo/migrations/fix_legacy_tags_test.exs
index 432055e45..adfed1142 100644
--- a/test/pleroma/repo/migrations/fix_legacy_tags_test.exs
+++ b/test/pleroma/repo/migrations/fix_legacy_tags_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.Repo.Migrations.FixLegacyTagsTest do
   alias Pleroma.User
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   import Pleroma.Tests.Helpers
 
diff --git a/test/pleroma/repo/migrations/move_welcome_settings_test.exs b/test/pleroma/repo/migrations/move_welcome_settings_test.exs
index 53d05a55a..5dbe9d7b0 100644
--- a/test/pleroma/repo/migrations/move_welcome_settings_test.exs
+++ b/test/pleroma/repo/migrations/move_welcome_settings_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Repo.Migrations.MoveWelcomeSettingsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   import Pleroma.Tests.Helpers
   alias Pleroma.ConfigDB
diff --git a/test/pleroma/repo_test.exs b/test/pleroma/repo_test.exs
index 155791be2..eaddef3a6 100644
--- a/test/pleroma/repo_test.exs
+++ b/test/pleroma/repo_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.RepoTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.User
diff --git a/test/pleroma/report_note_test.exs b/test/pleroma/report_note_test.exs
index 25c1d6a61..cc4561eea 100644
--- a/test/pleroma/report_note_test.exs
+++ b/test/pleroma/report_note_test.exs
@@ -4,7 +4,7 @@
 
 defmodule Pleroma.ReportNoteTest do
   alias Pleroma.ReportNote
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   test "create/3" do
diff --git a/test/pleroma/reverse_proxy_test.exs b/test/pleroma/reverse_proxy_test.exs
index 8df63de65..0a2c169ce 100644
--- a/test/pleroma/reverse_proxy_test.exs
+++ b/test/pleroma/reverse_proxy_test.exs
@@ -3,8 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.ReverseProxyTest do
-  use Pleroma.Web.ConnCase, async: true
-
+  use Pleroma.Web.ConnCase
   import ExUnit.CaptureLog
   import Mox
 
diff --git a/test/pleroma/safe_jsonb_set_test.exs b/test/pleroma/safe_jsonb_set_test.exs
index 8b1274545..6d70f1026 100644
--- a/test/pleroma/safe_jsonb_set_test.exs
+++ b/test/pleroma/safe_jsonb_set_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.SafeJsonbSetTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   test "it doesn't wipe the object when asked to set the value to NULL" do
     assert %{rows: [[%{"key" => "value", "test" => nil}]]} =
diff --git a/test/pleroma/stats_test.exs b/test/pleroma/stats_test.exs
index 74bf785b0..6c2fd5726 100644
--- a/test/pleroma/stats_test.exs
+++ b/test/pleroma/stats_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.StatsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/upload/filter/dedupe_test.exs b/test/pleroma/upload/filter/dedupe_test.exs
index 92a3d7df3..6559cbb50 100644
--- a/test/pleroma/upload/filter/dedupe_test.exs
+++ b/test/pleroma/upload/filter/dedupe_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Upload.Filter.DedupeTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Upload
   alias Pleroma.Upload.Filter.Dedupe
diff --git a/test/pleroma/upload/filter/exiftool_test.exs b/test/pleroma/upload/filter/exiftool_test.exs
index 6b978b64c..b5a5ba18d 100644
--- a/test/pleroma/upload/filter/exiftool_test.exs
+++ b/test/pleroma/upload/filter/exiftool_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Upload.Filter.ExiftoolTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Upload.Filter
 
   test "apply exiftool filter" do
diff --git a/test/pleroma/uploaders/local_test.exs b/test/pleroma/uploaders/local_test.exs
index 1ce7be485..5b377d580 100644
--- a/test/pleroma/uploaders/local_test.exs
+++ b/test/pleroma/uploaders/local_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Uploaders.LocalTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Uploaders.Local
 
   describe "get_file/1" do
diff --git a/test/pleroma/user/notification_setting_test.exs b/test/pleroma/user/notification_setting_test.exs
index 308da216a..701130380 100644
--- a/test/pleroma/user/notification_setting_test.exs
+++ b/test/pleroma/user/notification_setting_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.User.NotificationSettingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.User.NotificationSetting
 
diff --git a/test/pleroma/user_relationship_test.exs b/test/pleroma/user_relationship_test.exs
index f12406097..da4982065 100644
--- a/test/pleroma/user_relationship_test.exs
+++ b/test/pleroma/user_relationship_test.exs
@@ -5,7 +5,7 @@
 defmodule Pleroma.UserRelationshipTest do
   alias Pleroma.UserRelationship
 
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/activity_pub/mrf/anti_followbot_policy_test.exs b/test/pleroma/web/activity_pub/mrf/anti_followbot_policy_test.exs
index 3c795f5ac..49bbc271d 100644
--- a/test/pleroma/web/activity_pub/mrf/anti_followbot_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/anti_followbot_policy_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy
diff --git a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs
index 9a283f27d..19ea491c0 100644
--- a/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/ensure_re_prepended_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Object
diff --git a/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs b/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs
index 86dd9ddae..b5f401ad2 100644
--- a/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/force_bot_unlisted_policy_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicyTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy
diff --git a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
index 64ea61dd4..d03456b34 100644
--- a/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/no_placeholder_text_policy_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy
 
   test "it clears content object" do
diff --git a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs
index 9b39c45bd..5fccf7760 100644
--- a/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/normalize_markup_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup
 
   @html_sample """
diff --git a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs
index ffc30ba62..4f289739f 100644
--- a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.Web.ActivityPub.MRF.TagPolicy
diff --git a/test/pleroma/web/activity_pub/object_validators/accept_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/accept_validation_test.exs
index d6111ba41..bafa2a672 100644
--- a/test/pleroma/web/activity_pub/object_validators/accept_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/accept_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.AcceptValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
index 4771c4698..9613dea9b 100644
--- a/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/announce_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Object
   alias Pleroma.Web.ActivityPub.Builder
diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_validator_test.exs
index cc6dab872..1f992b397 100644
--- a/test/pleroma/web/activity_pub/object_validators/article_note_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/article_note_validator_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidatorTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator
   alias Pleroma.Web.ActivityPub.Utils
diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
index 2e1975a79..45e1d8852 100644
--- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/block_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/block_validation_test.exs
index c08d4b2e8..d133aeb1a 100644
--- a/test/pleroma/web/activity_pub/object_validators/block_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/block_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs
index 02683b899..57de83c8a 100644
--- a/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/delete_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Object
   alias Pleroma.Web.ActivityPub.Builder
diff --git a/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
index 582e6d785..342cfeef8 100644
--- a/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/emoji_react_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/follow_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/follow_validation_test.exs
index 6e1378be2..0f77ac8df 100644
--- a/test/pleroma/web/activity_pub/object_validators/follow_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/follow_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
index 2c033b7e2..4cda3742d 100644
--- a/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/like_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.ObjectValidator
   alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/reject_validation_test.exs b/test/pleroma/web/activity_pub/object_validators/reject_validation_test.exs
index 370bb6e5c..69f5e8ac4 100644
--- a/test/pleroma/web/activity_pub/object_validators/reject_validation_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/reject_validation_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.RejectValidationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
index 75bbcc4b6..dc85d1ac3 100644
--- a/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/undo_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
index 5e80cf731..2c4a50bfd 100644
--- a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.ActivityPub.Builder
   alias Pleroma.Web.ActivityPub.ObjectValidator
diff --git a/test/pleroma/web/activity_pub/pipeline_test.exs b/test/pleroma/web/activity_pub/pipeline_test.exs
index 210a06563..d568d825b 100644
--- a/test/pleroma/web/activity_pub/pipeline_test.exs
+++ b/test/pleroma/web/activity_pub/pipeline_test.exs
@@ -3,14 +3,35 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.PipelineTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
-  import Mock
+  import Mox
   import Pleroma.Factory
 
+  alias Pleroma.ConfigMock
+  alias Pleroma.Web.ActivityPub.ActivityPubMock
+  alias Pleroma.Web.ActivityPub.MRFMock
+  alias Pleroma.Web.ActivityPub.ObjectValidatorMock
+  alias Pleroma.Web.ActivityPub.SideEffectsMock
+  alias Pleroma.Web.FederatorMock
+
+  setup :verify_on_exit!
+
   describe "common_pipeline/2" do
     setup do
-      clear_config([:instance, :federating], true)
+      ObjectValidatorMock
+      |> expect(:validate, fn o, m -> {:ok, o, m} end)
+
+      MRFMock
+      |> expect(:pipeline_filter, fn o, m -> {:ok, o, m} end)
+
+      ActivityPubMock
+      |> expect(:persist, fn o, m -> {:ok, o, m} end)
+
+      SideEffectsMock
+      |> expect(:handle, fn o, m -> {:ok, o, m} end)
+      |> expect(:handle_after_transaction, fn m -> m end)
+
       :ok
     end
 
@@ -21,159 +42,53 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
 
       activity_with_object = %{activity | data: Map.put(activity.data, "object", object)}
 
-      with_mocks([
-        {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
-        {
-          Pleroma.Web.ActivityPub.MRF,
-          [],
-          [pipeline_filter: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.ActivityPub,
-          [],
-          [persist: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.SideEffects,
-          [],
-          [
-            handle: fn o, m -> {:ok, o, m} end,
-            handle_after_transaction: fn m -> m end
-          ]
-        },
-        {
-          Pleroma.Web.Federator,
-          [],
-          [publish: fn _o -> :ok end]
-        }
-      ]) do
-        assert {:ok, ^activity, ^meta} =
-                 Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
+      FederatorMock
+      |> expect(:publish, fn ^activity_with_object -> :ok end)
 
-        assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
-        refute called(Pleroma.Web.Federator.publish(activity))
-        assert_called(Pleroma.Web.Federator.publish(activity_with_object))
-      end
+      ConfigMock
+      |> expect(:get, fn [:instance, :federating] -> true end)
+
+      assert {:ok, ^activity, ^meta} =
+               Pleroma.Web.ActivityPub.Pipeline.common_pipeline(
+                 activity,
+                 meta
+               )
     end
 
     test "it goes through validation, filtering, persisting, side effects and federation for local activities" do
       activity = insert(:note_activity)
       meta = [local: true]
 
-      with_mocks([
-        {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
-        {
-          Pleroma.Web.ActivityPub.MRF,
-          [],
-          [pipeline_filter: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.ActivityPub,
-          [],
-          [persist: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.SideEffects,
-          [],
-          [
-            handle: fn o, m -> {:ok, o, m} end,
-            handle_after_transaction: fn m -> m end
-          ]
-        },
-        {
-          Pleroma.Web.Federator,
-          [],
-          [publish: fn _o -> :ok end]
-        }
-      ]) do
-        assert {:ok, ^activity, ^meta} =
-                 Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
+      FederatorMock
+      |> expect(:publish, fn ^activity -> :ok end)
 
-        assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
-        assert_called(Pleroma.Web.Federator.publish(activity))
-      end
+      ConfigMock
+      |> expect(:get, fn [:instance, :federating] -> true end)
+
+      assert {:ok, ^activity, ^meta} =
+               Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
     end
 
     test "it goes through validation, filtering, persisting, side effects without federation for remote activities" do
       activity = insert(:note_activity)
       meta = [local: false]
 
-      with_mocks([
-        {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
-        {
-          Pleroma.Web.ActivityPub.MRF,
-          [],
-          [pipeline_filter: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.ActivityPub,
-          [],
-          [persist: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.SideEffects,
-          [],
-          [handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
-        },
-        {
-          Pleroma.Web.Federator,
-          [],
-          []
-        }
-      ]) do
-        assert {:ok, ^activity, ^meta} =
-                 Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
+      ConfigMock
+      |> expect(:get, fn [:instance, :federating] -> true end)
 
-        assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
-      end
+      assert {:ok, ^activity, ^meta} =
+               Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
     end
 
     test "it goes through validation, filtering, persisting, side effects without federation for local activities if federation is deactivated" do
-      clear_config([:instance, :federating], false)
-
       activity = insert(:note_activity)
       meta = [local: true]
 
-      with_mocks([
-        {Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
-        {
-          Pleroma.Web.ActivityPub.MRF,
-          [],
-          [pipeline_filter: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.ActivityPub,
-          [],
-          [persist: fn o, m -> {:ok, o, m} end]
-        },
-        {
-          Pleroma.Web.ActivityPub.SideEffects,
-          [],
-          [handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
-        },
-        {
-          Pleroma.Web.Federator,
-          [],
-          []
-        }
-      ]) do
-        assert {:ok, ^activity, ^meta} =
-                 Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
+      ConfigMock
+      |> expect(:get, fn [:instance, :federating] -> false end)
 
-        assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.MRF.pipeline_filter(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
-        assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
-      end
+      assert {:ok, ^activity, ^meta} =
+               Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
     end
   end
 end
diff --git a/test/pleroma/web/activity_pub/relay_test.exs b/test/pleroma/web/activity_pub/relay_test.exs
index 3284980f7..a7cd732bb 100644
--- a/test/pleroma/web/activity_pub/relay_test.exs
+++ b/test/pleroma/web/activity_pub/relay_test.exs
@@ -84,7 +84,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
              )
 
       Pleroma.Repo.delete(user)
-      Cachex.clear(:user_cache)
+      User.invalidate_cache(user)
 
       assert {:ok, %Activity{} = activity} = Relay.unfollow(user_ap_id, %{force: true})
 
diff --git a/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
index 485216487..d356fcc72 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/accept_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.AcceptHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.Transmogrifier
diff --git a/test/pleroma/web/activity_pub/transmogrifier/block_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/block_handling_test.exs
index 679c33c6c..6adad88f5 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/block_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/block_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.BlockHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.User
diff --git a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
index cffaa7c44..1f9e73ff8 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/delete_handling_test.exs
@@ -51,6 +51,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
       Object.normalize(activity.data["object"])
       |> Repo.delete()
 
+    # TODO: mock cachex
     Cachex.del(:object_cache, "object:#{object.data["id"]}")
 
     deleting_user = insert(:user)
diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
index aea4ed6f8..1ebf6b1e8 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Object
diff --git a/test/pleroma/web/activity_pub/transmogrifier/like_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/like_handling_test.exs
index 967bad151..35211b8f2 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/like_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/like_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.LikeHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Web.ActivityPub.Transmogrifier
diff --git a/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
index 5a3bef792..851236758 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/reject_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.RejectHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.User
diff --git a/test/pleroma/web/activity_pub/transmogrifier/undo_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/undo_handling_test.exs
index fcfc7b4b6..107121ef8 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/undo_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/undo_handling_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier.UndoHandlingTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Object
diff --git a/test/pleroma/web/activity_pub/transmogrifier/user_update_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/user_update_handling_test.exs
index c62d5e139..8ed5e5e90 100644
--- a/test/pleroma/web/activity_pub/transmogrifier/user_update_handling_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier/user_update_handling_test.exs
@@ -103,7 +103,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.UserUpdateHandlingTest do
              %{"name" => "foo1", "value" => "updated"}
            ]
 
-    Pleroma.Config.put([:instance, :max_remote_account_fields], 2)
+    clear_config([:instance, :max_remote_account_fields], 2)
 
     update_data =
       update_data
diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs
index be9cd7d13..2263b6091 100644
--- a/test/pleroma/web/activity_pub/utils_test.exs
+++ b/test/pleroma/web/activity_pub/utils_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.UtilsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Activity
   alias Pleroma.Object
   alias Pleroma.Repo
diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs
index 98c7c9d09..fe6ddf0d6 100644
--- a/test/pleroma/web/activity_pub/views/user_view_test.exs
+++ b/test/pleroma/web/activity_pub/views/user_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.UserViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.User
diff --git a/test/pleroma/web/activity_pub/visibility_test.exs b/test/pleroma/web/activity_pub/visibility_test.exs
index 836d44994..1ec41aa19 100644
--- a/test/pleroma/web/activity_pub/visibility_test.exs
+++ b/test/pleroma/web/activity_pub/visibility_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.VisibilityTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Activity
   alias Pleroma.Web.ActivityPub.Visibility
@@ -159,7 +159,7 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do
          user: user
        } do
     Repo.delete(user)
-    Cachex.clear(:user_cache)
+    Pleroma.User.invalidate_cache(user)
     refute Visibility.is_private?(direct)
   end
 
diff --git a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs
index 5aefa1e60..dead1c09e 100644
--- a/test/pleroma/web/admin_api/controllers/chat_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/chat_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/admin_api/controllers/config_controller_test.exs b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
index e6b203e74..df5d74d45 100644
--- a/test/pleroma/web/admin_api/controllers/config_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/config_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
-  use Pleroma.Web.ConnCase, async: true
+  use Pleroma.Web.ConnCase
 
   import ExUnit.CaptureLog
   import Pleroma.Factory
diff --git a/test/pleroma/web/admin_api/controllers/media_proxy_cache_controller_test.exs b/test/pleroma/web/admin_api/controllers/media_proxy_cache_controller_test.exs
index f243d1fb2..62fb9592a 100644
--- a/test/pleroma/web/admin_api/controllers/media_proxy_cache_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/media_proxy_cache_controller_test.exs
@@ -12,10 +12,6 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
 
   setup do: clear_config([:media_proxy])
 
-  setup do
-    on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
-  end
-
   setup do
     admin = insert(:user, is_admin: true)
     token = insert(:oauth_admin_token, user: admin)
diff --git a/test/pleroma/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs
index cbfc2e7b0..2ab2f2f6d 100644
--- a/test/pleroma/web/admin_api/controllers/report_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/report_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/admin_api/controllers/status_controller_test.exs b/test/pleroma/web/admin_api/controllers/status_controller_test.exs
index a18ef9e4b..40714c8a4 100644
--- a/test/pleroma/web/admin_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/status_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/admin_api/search_test.exs b/test/pleroma/web/admin_api/search_test.exs
index 9bc58640c..fdf22a8e6 100644
--- a/test/pleroma/web/admin_api/search_test.exs
+++ b/test/pleroma/web/admin_api/search_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.SearchTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.AdminAPI.Search
 
diff --git a/test/pleroma/web/admin_api/views/moderation_log_view_test.exs b/test/pleroma/web/admin_api/views/moderation_log_view_test.exs
index e6c5aaa7f..390d7bbeb 100644
--- a/test/pleroma/web/admin_api/views/moderation_log_view_test.exs
+++ b/test/pleroma/web/admin_api/views/moderation_log_view_test.exs
@@ -2,7 +2,7 @@
 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 defmodule Pleroma.Web.AdminAPI.ModerationLogViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.AdminAPI.ModerationLogView
 
diff --git a/test/pleroma/web/admin_api/views/report_view_test.exs b/test/pleroma/web/admin_api/views/report_view_test.exs
index 5a02292be..ff3453208 100644
--- a/test/pleroma/web/admin_api/views/report_view_test.exs
+++ b/test/pleroma/web/admin_api/views/report_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.AdminAPI.ReportViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/auth/authenticator_test.exs b/test/pleroma/web/auth/authenticator_test.exs
index d54253343..862eb8051 100644
--- a/test/pleroma/web/auth/authenticator_test.exs
+++ b/test/pleroma/web/auth/authenticator_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Auth.AuthenticatorTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.Auth.Authenticator
   import Pleroma.Factory
diff --git a/test/pleroma/web/auth/basic_auth_test.exs b/test/pleroma/web/auth/basic_auth_test.exs
index bf6e3d2fc..e56c1e1e8 100644
--- a/test/pleroma/web/auth/basic_auth_test.exs
+++ b/test/pleroma/web/auth/basic_auth_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Auth.BasicAuthTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/auth/pleroma_authenticator_test.exs b/test/pleroma/web/auth/pleroma_authenticator_test.exs
index 1ba0dfecc..4539ffe87 100644
--- a/test/pleroma/web/auth/pleroma_authenticator_test.exs
+++ b/test/pleroma/web/auth/pleroma_authenticator_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.Auth.PleromaAuthenticator
   import Pleroma.Factory
diff --git a/test/pleroma/web/auth/totp_authenticator_test.exs b/test/pleroma/web/auth/totp_authenticator_test.exs
index 84d4cd840..7f99d62bf 100644
--- a/test/pleroma/web/auth/totp_authenticator_test.exs
+++ b/test/pleroma/web/auth/totp_authenticator_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Auth.TOTPAuthenticatorTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.MFA
   alias Pleroma.MFA.BackupCodes
diff --git a/test/pleroma/web/endpoint/metrics_exporter_test.exs b/test/pleroma/web/endpoint/metrics_exporter_test.exs
index 875addc96..d0cae3d42 100644
--- a/test/pleroma/web/endpoint/metrics_exporter_test.exs
+++ b/test/pleroma/web/endpoint/metrics_exporter_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Endpoint.MetricsExporterTest do
+  # Modifies AppEnv, has to stay synchronous
   use Pleroma.Web.ConnCase
 
   alias Pleroma.Web.Endpoint.MetricsExporter
diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
index 3361c8669..f6285853a 100644
--- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs
@@ -1411,8 +1411,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
                |> json_response_and_validate_schema(:ok)
 
       assert Token |> Repo.get_by(token: access_token) |> Repo.preload(:user) |> Map.get(:user)
-
-      Cachex.del(:used_captcha_cache, token)
     end
 
     test "returns 400 if any captcha field is not provided", %{conn: conn} do
diff --git a/test/pleroma/web/mastodon_api/controllers/auth_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/auth_controller_test.exs
index d7834c876..ce957054b 100644
--- a/test/pleroma/web/mastodon_api/controllers/auth_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/auth_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Config
   alias Pleroma.Repo
diff --git a/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs
index b00615ac9..a03513e06 100644
--- a/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/conversation_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Conversation.Participation
   alias Pleroma.User
diff --git a/test/pleroma/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/domain_block_controller_test.exs
index 664654500..b10aa6966 100644
--- a/test/pleroma/web/mastodon_api/controllers/domain_block_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/domain_block_controller_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do
+  # TODO: Should not need Cachex
   use Pleroma.Web.ConnCase
 
   alias Pleroma.User
diff --git a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
index 0d426ec34..e639cdde1 100644
--- a/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/filter_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.MastodonAPI.FilterView
 
diff --git a/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
index b977b41ae..f0a466212 100644
--- a/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/follow_request_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI
diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
index 605df6ed6..71a170240 100644
--- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
+  # TODO: Should not need Cachex
   use Pleroma.Web.ConnCase
 
   alias Pleroma.User
diff --git a/test/pleroma/web/mastodon_api/controllers/list_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/list_controller_test.exs
index 091ec006c..01f64cfcc 100644
--- a/test/pleroma/web/mastodon_api/controllers/list_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/list_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ListControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Repo
 
diff --git a/test/pleroma/web/mastodon_api/controllers/marker_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/marker_controller_test.exs
index 9f0481120..ee944a67c 100644
--- a/test/pleroma/web/mastodon_api/controllers/marker_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/marker_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs
index f41de6448..95e27623d 100644
--- a/test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/poll_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.PollControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Object
   alias Pleroma.Web.CommonAPI
diff --git a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs
index 6636cff96..322eb475c 100644
--- a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.CommonAPI
 
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index 30d542dfa..de542e5df 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -67,10 +67,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
           "sensitive" => "0"
         })
 
-      {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
-      # Six hours
-      assert ttl > :timer.seconds(6 * 60 * 60 - 1)
-
       assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
                json_response_and_validate_schema(conn_one, 200)
 
diff --git a/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs
index 5ef39bdb2..4bb085750 100644
--- a/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/subscription_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
index 7f08e187c..c3471266a 100644
--- a/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/suggestion_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   setup do: oauth_access(["read"])
 
diff --git a/test/pleroma/web/mastodon_api/mastodon_api_controller_test.exs b/test/pleroma/web/mastodon_api/mastodon_api_controller_test.exs
index bb4bc4396..be5bf68a3 100644
--- a/test/pleroma/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/mastodon_api_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   describe "empty_array/2 (stubs)" do
     test "GET /api/v1/accounts/:id/identity_proofs" do
diff --git a/test/pleroma/web/mastodon_api/mastodon_api_test.exs b/test/pleroma/web/mastodon_api/mastodon_api_test.exs
index 687fe5585..cf7f464be 100644
--- a/test/pleroma/web/mastodon_api/mastodon_api_test.exs
+++ b/test/pleroma/web/mastodon_api/mastodon_api_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Notification
   alias Pleroma.ScheduledActivity
diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs
index ed1921c91..023726468 100644
--- a/test/pleroma/web/mastodon_api/update_credentials_test.exs
+++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs
@@ -11,8 +11,6 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
   import Mock
   import Pleroma.Factory
 
-  setup do: clear_config([:instance, :max_account_fields])
-
   describe "updating credentials" do
     setup do: oauth_access(["write:accounts"])
     setup :request_content_type
@@ -446,7 +444,7 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
                |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
                |> json_response_and_validate_schema(403)
 
-      Pleroma.Config.put([:instance, :max_account_fields], 1)
+      clear_config([:instance, :max_account_fields], 1)
 
       fields = [
         %{"name" => "foo", "value" => "bar"},
diff --git a/test/pleroma/web/mastodon_api/views/conversation_view_test.exs b/test/pleroma/web/mastodon_api/views/conversation_view_test.exs
index 20c10ba3d..f02253b68 100644
--- a/test/pleroma/web/mastodon_api/views/conversation_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/conversation_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Conversation.Participation
   alias Pleroma.Web.CommonAPI
diff --git a/test/pleroma/web/mastodon_api/views/list_view_test.exs b/test/pleroma/web/mastodon_api/views/list_view_test.exs
index ca99242cb..377941332 100644
--- a/test/pleroma/web/mastodon_api/views/list_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/list_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ListViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.MastodonAPI.ListView
 
diff --git a/test/pleroma/web/mastodon_api/views/marker_view_test.exs b/test/pleroma/web/mastodon_api/views/marker_view_test.exs
index 48a0a6d33..a0bec758f 100644
--- a/test/pleroma/web/mastodon_api/views/marker_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/marker_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.MastodonAPI.MarkerView
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs
index 04f73f5a0..c41ac7f7f 100644
--- a/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.ScheduledActivity
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.CommonAPI
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
index 6b8afc960..22717ce90 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -160,7 +160,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
     {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"})
 
     Repo.delete(user)
-    Cachex.clear(:user_cache)
+    User.invalidate_cache(user)
 
     finger_url =
       "https://localhost/.well-known/webfinger?resource=acct:#{user.nickname}@localhost"
@@ -194,7 +194,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
       |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"})
       |> Repo.update()
 
-    Cachex.clear(:user_cache)
+    User.invalidate_cache(user)
 
     result = StatusView.render("show.json", activity: activity)
 
diff --git a/test/pleroma/web/mastodon_api/views/subscription_view_test.exs b/test/pleroma/web/mastodon_api/views/subscription_view_test.exs
index 981524c0e..c2bb535c5 100644
--- a/test/pleroma/web/mastodon_api/views/subscription_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/subscription_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.SubscriptionViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.MastodonAPI.SubscriptionView, as: View
   alias Pleroma.Web.Push
diff --git a/test/pleroma/web/media_proxy/invalidation/http_test.exs b/test/pleroma/web/media_proxy/invalidation/http_test.exs
index 13d081325..c81010423 100644
--- a/test/pleroma/web/media_proxy/invalidation/http_test.exs
+++ b/test/pleroma/web/media_proxy/invalidation/http_test.exs
@@ -9,10 +9,6 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
   import ExUnit.CaptureLog
   import Tesla.Mock
 
-  setup do
-    on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
-  end
-
   test "logs hasn't error message when request is valid" do
     mock(fn
       %{method: :purge, url: "http://example.com/media/example.jpg"} ->
diff --git a/test/pleroma/web/media_proxy/invalidation/script_test.exs b/test/pleroma/web/media_proxy/invalidation/script_test.exs
index 692cbb2df..6940a4539 100644
--- a/test/pleroma/web/media_proxy/invalidation/script_test.exs
+++ b/test/pleroma/web/media_proxy/invalidation/script_test.exs
@@ -3,15 +3,11 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
-  use ExUnit.Case
+  use ExUnit.Case, async: true
   alias Pleroma.Web.MediaProxy.Invalidation
 
   import ExUnit.CaptureLog
 
-  setup do
-    on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
-  end
-
   test "it logger error when script not found" do
     assert capture_log(fn ->
              assert Invalidation.Script.purge(
diff --git a/test/pleroma/web/media_proxy/invalidation_test.exs b/test/pleroma/web/media_proxy/invalidation_test.exs
index aa1435ac0..b7be36b47 100644
--- a/test/pleroma/web/media_proxy/invalidation_test.exs
+++ b/test/pleroma/web/media_proxy/invalidation_test.exs
@@ -3,8 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MediaProxy.InvalidationTest do
-  use ExUnit.Case
-  use Pleroma.Tests.Helpers
+  use Pleroma.DataCase
 
   alias Pleroma.Config
   alias Pleroma.Web.MediaProxy.Invalidation
@@ -15,10 +14,6 @@ defmodule Pleroma.Web.MediaProxy.InvalidationTest do
 
   setup do: clear_config([:media_proxy])
 
-  setup do
-    on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
-  end
-
   describe "Invalidation.Http" do
     test "perform request to clear cache" do
       Config.put([:media_proxy, :enabled], false)
diff --git a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
index e9b584822..65cf2a01b 100644
--- a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs
@@ -10,10 +10,6 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
   alias Pleroma.Web.MediaProxy
   alias Plug.Conn
 
-  setup do
-    on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
-  end
-
   describe "Media Proxy" do
     setup do
       clear_config([:media_proxy, :enabled], true)
diff --git a/test/pleroma/web/metadata/player_view_test.exs b/test/pleroma/web/metadata/player_view_test.exs
index e6c990242..6d22317d2 100644
--- a/test/pleroma/web/metadata/player_view_test.exs
+++ b/test/pleroma/web/metadata/player_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Metadata.PlayerViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.Metadata.PlayerView
 
diff --git a/test/pleroma/web/metadata/providers/feed_test.exs b/test/pleroma/web/metadata/providers/feed_test.exs
index e6e5cc5ed..c7359e00b 100644
--- a/test/pleroma/web/metadata/providers/feed_test.exs
+++ b/test/pleroma/web/metadata/providers/feed_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Metadata.Providers.FeedTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.Metadata.Providers.Feed
 
diff --git a/test/pleroma/web/metadata/providers/rel_me_test.exs b/test/pleroma/web/metadata/providers/rel_me_test.exs
index 2293d6e13..ae449c052 100644
--- a/test/pleroma/web/metadata/providers/rel_me_test.exs
+++ b/test/pleroma/web/metadata/providers/rel_me_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Metadata.Providers.RelMeTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.Metadata.Providers.RelMe
 
diff --git a/test/pleroma/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs
index 8183256d8..3794db766 100644
--- a/test/pleroma/web/metadata/utils_test.exs
+++ b/test/pleroma/web/metadata/utils_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Metadata.UtilsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.Metadata.Utils
 
diff --git a/test/pleroma/web/mongoose_im_controller_test.exs b/test/pleroma/web/mongoose_im_controller_test.exs
index e3a8aa3d8..4590e1296 100644
--- a/test/pleroma/web/mongoose_im_controller_test.exs
+++ b/test/pleroma/web/mongoose_im_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MongooseIMControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
   import Pleroma.Factory
 
   test "/user_exists", %{conn: conn} do
diff --git a/test/pleroma/web/o_auth/app_test.exs b/test/pleroma/web/o_auth/app_test.exs
index 993a490e0..24d7049f1 100644
--- a/test/pleroma/web/o_auth/app_test.exs
+++ b/test/pleroma/web/o_auth/app_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OAuth.AppTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.OAuth.App
   import Pleroma.Factory
diff --git a/test/pleroma/web/o_auth/authorization_test.exs b/test/pleroma/web/o_auth/authorization_test.exs
index d74b26cf8..d1920962c 100644
--- a/test/pleroma/web/o_auth/authorization_test.exs
+++ b/test/pleroma/web/o_auth/authorization_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OAuth.AuthorizationTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.OAuth.App
   alias Pleroma.Web.OAuth.Authorization
   import Pleroma.Factory
diff --git a/test/pleroma/web/o_auth/mfa_controller_test.exs b/test/pleroma/web/o_auth/mfa_controller_test.exs
index 6ecd0f6c9..bc50d8d18 100644
--- a/test/pleroma/web/o_auth/mfa_controller_test.exs
+++ b/test/pleroma/web/o_auth/mfa_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OAuth.MFAControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.MFA
diff --git a/test/pleroma/web/o_auth/token/utils_test.exs b/test/pleroma/web/o_auth/token/utils_test.exs
index a610d92f8..3444692ec 100644
--- a/test/pleroma/web/o_auth/token/utils_test.exs
+++ b/test/pleroma/web/o_auth/token/utils_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OAuth.Token.UtilsTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.OAuth.Token.Utils
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/o_auth/token_test.exs b/test/pleroma/web/o_auth/token_test.exs
index c88b9cc98..866f1c00a 100644
--- a/test/pleroma/web/o_auth/token_test.exs
+++ b/test/pleroma/web/o_auth/token_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.OAuth.TokenTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Repo
   alias Pleroma.Web.OAuth.App
   alias Pleroma.Web.OAuth.Authorization
diff --git a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs
index a6c9d0c1b..415c3decd 100644
--- a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs
@@ -394,11 +394,11 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
       tridi = insert(:user)
 
       {:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
-      :timer.sleep(1000)
-      {:ok, _chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
-      :timer.sleep(1000)
+      {:ok, chat_1} = time_travel(chat_1, -3)
+      {:ok, chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
+      {:ok, _chat_2} = time_travel(chat_2, -2)
       {:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
-      :timer.sleep(1000)
+      {:ok, chat_3} = time_travel(chat_3, -1)
 
       # bump the second one
       {:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
diff --git a/test/pleroma/web/pleroma_api/controllers/conversation_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/conversation_controller_test.exs
index f2feeaaef..c8c2433ae 100644
--- a/test/pleroma/web/pleroma_api/controllers/conversation_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/conversation_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.ConversationControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Conversation.Participation
   alias Pleroma.Repo
diff --git a/test/pleroma/web/pleroma_api/controllers/mascot_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/mascot_controller_test.exs
index 289119d45..5f8fa03f6 100644
--- a/test/pleroma/web/pleroma_api/controllers/mascot_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/mascot_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.User
 
diff --git a/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
index bb4fe6c49..03af4d70c 100644
--- a/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/notification_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Notification
   alias Pleroma.Repo
diff --git a/test/pleroma/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/scrobble_controller_test.exs
index f39c07ac6..4ab6d9132 100644
--- a/test/pleroma/web/pleroma_api/controllers/scrobble_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/scrobble_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   alias Pleroma.Web.CommonAPI
 
diff --git a/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
index 22988c881..8d4e0104a 100644
--- a/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
+++ b/test/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.TwoFactorAuthenticationControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
   import Pleroma.Factory
   alias Pleroma.MFA.Settings
diff --git a/test/pleroma/web/pleroma_api/views/chat_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_view_test.exs
index 02484b705..b60b597e8 100644
--- a/test/pleroma/web/pleroma_api/views/chat_view_test.exs
+++ b/test/pleroma/web/pleroma_api/views/chat_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Chat
   alias Pleroma.Chat.MessageReference
diff --git a/test/pleroma/web/pleroma_api/views/scrobble_view_test.exs b/test/pleroma/web/pleroma_api/views/scrobble_view_test.exs
index 0f43cbdc3..113b8f690 100644
--- a/test/pleroma/web/pleroma_api/views/scrobble_view_test.exs
+++ b/test/pleroma/web/pleroma_api/views/scrobble_view_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.PleromaAPI.ScrobbleViewTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   alias Pleroma.Web.PleromaAPI.ScrobbleView
 
diff --git a/test/pleroma/web/plugs/cache_control_test.exs b/test/pleroma/web/plugs/cache_control_test.exs
index fcf3d2be8..c775787ca 100644
--- a/test/pleroma/web/plugs/cache_control_test.exs
+++ b/test/pleroma/web/plugs/cache_control_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.CacheControlTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
   alias Plug.Conn
 
   test "Verify Cache-Control header on static assets", %{conn: conn} do
diff --git a/test/pleroma/web/plugs/cache_test.exs b/test/pleroma/web/plugs/cache_test.exs
index 93a66f5d3..0e5fa6f36 100644
--- a/test/pleroma/web/plugs/cache_test.exs
+++ b/test/pleroma/web/plugs/cache_test.exs
@@ -3,7 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.CacheTest do
-  use ExUnit.Case, async: true
+  # Relies on Cachex, has to stay synchronous
+  use Pleroma.DataCase
   use Plug.Test
 
   alias Pleroma.Web.Plugs.Cache
@@ -24,11 +25,6 @@ defmodule Pleroma.Web.Plugs.CacheTest do
 
   @ttl 5
 
-  setup do
-    Cachex.clear(:web_resp_cache)
-    :ok
-  end
-
   test "caches a response" do
     assert @miss_resp ==
              conn(:get, "/")
diff --git a/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs b/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs
index 211443a55..9f15f5c93 100644
--- a/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs
+++ b/test/pleroma/web/plugs/ensure_public_or_authenticated_plug_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlugTest do
-  use Pleroma.Web.ConnCase, async: true
+  use Pleroma.Web.ConnCase
 
   alias Pleroma.Config
   alias Pleroma.User
diff --git a/test/pleroma/web/plugs/idempotency_plug_test.exs b/test/pleroma/web/plugs/idempotency_plug_test.exs
index 4a7835993..ed8b3fc1a 100644
--- a/test/pleroma/web/plugs/idempotency_plug_test.exs
+++ b/test/pleroma/web/plugs/idempotency_plug_test.exs
@@ -3,7 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.IdempotencyPlugTest do
-  use ExUnit.Case, async: true
+  # Relies on Cachex, has to stay synchronous
+  use Pleroma.DataCase
   use Plug.Test
 
   alias Pleroma.Web.Plugs.IdempotencyPlug
diff --git a/test/pleroma/web/plugs/uploaded_media_plug_test.exs b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
index 7c8313121..bae9208ec 100644
--- a/test/pleroma/web/plugs/uploaded_media_plug_test.exs
+++ b/test/pleroma/web/plugs/uploaded_media_plug_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.UploadedMediaPlugTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
   alias Pleroma.Upload
 
   defp upload_file(context) do
diff --git a/test/pleroma/web/plugs/user_enabled_plug_test.exs b/test/pleroma/web/plugs/user_enabled_plug_test.exs
index 71c56f03a..e9c9e5f3e 100644
--- a/test/pleroma/web/plugs/user_enabled_plug_test.exs
+++ b/test/pleroma/web/plugs/user_enabled_plug_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Plugs.UserEnabledPlugTest do
-  use Pleroma.Web.ConnCase, async: true
+  use Pleroma.Web.ConnCase
 
   alias Pleroma.Web.Plugs.UserEnabledPlug
   import Pleroma.Factory
diff --git a/test/pleroma/web/preload/providers/user_test.exs b/test/pleroma/web/preload/providers/user_test.exs
index 83f065e27..6be03af79 100644
--- a/test/pleroma/web/preload/providers/user_test.exs
+++ b/test/pleroma/web/preload/providers/user_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Preload.Providers.UserTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
   alias Pleroma.Web.Preload.Providers.User
 
diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs
index 2a4a8fd06..326a67963 100644
--- a/test/pleroma/web/push/impl_test.exs
+++ b/test/pleroma/web/push/impl_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.Push.ImplTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
 
   import Pleroma.Factory
 
diff --git a/test/pleroma/web/rel_me_test.exs b/test/pleroma/web/rel_me_test.exs
index 65255916d..811cb0893 100644
--- a/test/pleroma/web/rel_me_test.exs
+++ b/test/pleroma/web/rel_me_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.RelMeTest do
-  use ExUnit.Case
+  use Pleroma.DataCase
 
   setup_all do
     Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
diff --git a/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs b/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
index 2f17bebd7..242521138 100644
--- a/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
+++ b/test/pleroma/web/rich_media/parser/ttl/aws_signed_url_test.exs
@@ -3,7 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrlTest do
-  use ExUnit.Case, async: true
+  # Relies on Cachex, needs to be synchronous
+  use Pleroma.DataCase
 
   test "s3 signed url is parsed correct for expiration time" do
     url = "https://pleroma.social/amz"
diff --git a/test/pleroma/web/twitter_api/controller_test.exs b/test/pleroma/web/twitter_api/controller_test.exs
index 464d0ea2e..b3ca67637 100644
--- a/test/pleroma/web/twitter_api/controller_test.exs
+++ b/test/pleroma/web/twitter_api/controller_test.exs
@@ -3,11 +3,11 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.TwitterAPI.ControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
 
-  alias Pleroma.Builders.ActivityBuilder
   alias Pleroma.Repo
   alias Pleroma.User
+  alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.OAuth.Token
 
   import Pleroma.Factory
@@ -36,22 +36,20 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       other_user = insert(:user)
 
       {:ok, _activity} =
-        ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user})
+        CommonAPI.post(other_user, %{
+          status: "Hey @#{current_user.nickname}"
+        })
 
       response_conn =
         conn
-        |> assign(:user, current_user)
         |> get("/api/v1/notifications")
 
-      [notification] = response = json_response(response_conn, 200)
-
-      assert length(response) == 1
+      [notification] = json_response(response_conn, 200)
 
       assert notification["pleroma"]["is_seen"] == false
 
       response_conn =
         conn
-        |> assign(:user, current_user)
         |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
 
       [notification] = response = json_response(response_conn, 200)
diff --git a/test/pleroma/web/twitter_api/password_controller_test.exs b/test/pleroma/web/twitter_api/password_controller_test.exs
index 6d08075cc..c1f5bc5c7 100644
--- a/test/pleroma/web/twitter_api/password_controller_test.exs
+++ b/test/pleroma/web/twitter_api/password_controller_test.exs
@@ -37,8 +37,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
 
       user = insert(:user)
       {:ok, token} = PasswordResetToken.create_token(user)
-
-      :timer.sleep(2000)
+      {:ok, token} = time_travel(token, -2)
 
       response =
         conn
@@ -55,7 +54,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
 
       user = insert(:user)
       {:ok, token} = PasswordResetToken.create_token(user)
-      :timer.sleep(2000)
+      {:ok, token} = time_travel(token, -2)
       {:ok, _access_token} = Token.create(insert(:oauth_app), user, %{})
 
       params = %{
diff --git a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
index a3e784d13..dfe5b02be 100644
--- a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
+++ b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
@@ -14,18 +14,27 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
   import Pleroma.Factory
   import Ecto.Query
 
-  setup do
-    Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
-    :ok
-  end
-
   setup_all do: clear_config([:instance, :federating], true)
-  setup do: clear_config([:instance])
-  setup do: clear_config([:frontend_configurations, :pleroma_fe])
   setup do: clear_config([:user, :deny_follow_blocked])
 
   describe "GET /ostatus_subscribe - remote_follow/2" do
     test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do
+      Tesla.Mock.mock(fn
+        %{method: :get, url: "https://mastodon.social/users/emelie/statuses/101849165031453009"} ->
+          %Tesla.Env{
+            status: 200,
+            headers: [{"content-type", "application/activity+json"}],
+            body: File.read!("test/fixtures/tesla_mock/status.emelie.json")
+          }
+
+        %{method: :get, url: "https://mastodon.social/users/emelie"} ->
+          %Tesla.Env{
+            status: 200,
+            headers: [{"content-type", "application/activity+json"}],
+            body: File.read!("test/fixtures/tesla_mock/emelie.json")
+          }
+      end)
+
       assert conn
              |> get(
                remote_follow_path(conn, :follow, %{
@@ -36,6 +45,15 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
     end
 
     test "show follow account page if the `acct` is a account link", %{conn: conn} do
+      Tesla.Mock.mock(fn
+        %{method: :get, url: "https://mastodon.social/users/emelie"} ->
+          %Tesla.Env{
+            status: 200,
+            headers: [{"content-type", "application/activity+json"}],
+            body: File.read!("test/fixtures/tesla_mock/emelie.json")
+          }
+      end)
+
       response =
         conn
         |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
@@ -45,6 +63,15 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
     end
 
     test "show follow page if the `acct` is a account link", %{conn: conn} do
+      Tesla.Mock.mock(fn
+        %{method: :get, url: "https://mastodon.social/users/emelie"} ->
+          %Tesla.Env{
+            status: 200,
+            headers: [{"content-type", "application/activity+json"}],
+            body: File.read!("test/fixtures/tesla_mock/emelie.json")
+          }
+      end)
+
       user = insert(:user)
 
       response =
@@ -56,7 +83,14 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
       assert response =~ "Remote follow"
     end
 
-    test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
+    test "show follow page with error when user can not be fetched by `acct` link", %{conn: conn} do
+      Tesla.Mock.mock(fn
+        %{method: :get, url: "https://mastodon.social/users/not_found"} ->
+          %Tesla.Env{
+            status: 404
+          }
+      end)
+
       user = insert(:user)
 
       assert capture_log(fn ->
diff --git a/test/pleroma/web/twitter_api/twitter_api_test.exs b/test/pleroma/web/twitter_api/twitter_api_test.exs
index 4a418dee3..5586a9a13 100644
--- a/test/pleroma/web/twitter_api/twitter_api_test.exs
+++ b/test/pleroma/web/twitter_api/twitter_api_test.exs
@@ -428,10 +428,4 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
     assert is_binary(error)
     refute User.get_cached_by_nickname("lain")
   end
-
-  setup do
-    Supervisor.terminate_child(Pleroma.Supervisor, Cachex)
-    Supervisor.restart_child(Pleroma.Supervisor, Cachex)
-    :ok
-  end
 end
diff --git a/test/pleroma/web/uploader_controller_test.exs b/test/pleroma/web/uploader_controller_test.exs
index 21e518236..00f9e72ec 100644
--- a/test/pleroma/web/uploader_controller_test.exs
+++ b/test/pleroma/web/uploader_controller_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.UploaderControllerTest do
-  use Pleroma.Web.ConnCase
+  use Pleroma.Web.ConnCase, async: true
   alias Pleroma.Uploaders.Uploader
 
   describe "callback/2" do
diff --git a/test/pleroma/web/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs
index 19f33a975..cdb84ae1e 100644
--- a/test/pleroma/web/web_finger_test.exs
+++ b/test/pleroma/web/web_finger_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.WebFingerTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.Web.WebFinger
   import Pleroma.Factory
   import Tesla.Mock
diff --git a/test/pleroma/workers/cron/new_users_digest_worker_test.exs b/test/pleroma/workers/cron/new_users_digest_worker_test.exs
index 75c9aa4a3..e00ed6745 100644
--- a/test/pleroma/workers/cron/new_users_digest_worker_test.exs
+++ b/test/pleroma/workers/cron/new_users_digest_worker_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Workers.Cron.NewUsersDigestWorkerTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   import Pleroma.Factory
 
   alias Pleroma.Tests.ObanHelpers
diff --git a/test/pleroma/xml_builder_test.exs b/test/pleroma/xml_builder_test.exs
index 059384c34..a4c73359d 100644
--- a/test/pleroma/xml_builder_test.exs
+++ b/test/pleroma/xml_builder_test.exs
@@ -3,7 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.XmlBuilderTest do
-  use Pleroma.DataCase
+  use Pleroma.DataCase, async: true
   alias Pleroma.XmlBuilder
 
   test "Build a basic xml string from a tuple" do
diff --git a/test/support/cachex_proxy.ex b/test/support/cachex_proxy.ex
new file mode 100644
index 000000000..e296b5c6a
--- /dev/null
+++ b/test/support/cachex_proxy.ex
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.CachexProxy do
+  @behaviour Pleroma.Caching
+
+  @impl true
+  defdelegate get!(cache, key), to: Cachex
+
+  @impl true
+  defdelegate stream!(cache, key), to: Cachex
+
+  @impl true
+  defdelegate put(cache, key, value, options), to: Cachex
+
+  @impl true
+  defdelegate put(cache, key, value), to: Cachex
+
+  @impl true
+  defdelegate get_and_update(cache, key, func), to: Cachex
+
+  @impl true
+  defdelegate get(cache, key), to: Cachex
+
+  @impl true
+  defdelegate fetch!(cache, key, func), to: Cachex
+
+  @impl true
+  defdelegate expire_at(cache, str, num), to: Cachex
+
+  @impl true
+  defdelegate exists?(cache, key), to: Cachex
+
+  @impl true
+  defdelegate del(cache, key), to: Cachex
+
+  @impl true
+  defdelegate execute!(cache, func), to: Cachex
+end
diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex
index 114184a9f..f4696adb3 100644
--- a/test/support/channel_case.ex
+++ b/test/support/channel_case.ex
@@ -33,8 +33,14 @@ defmodule Pleroma.Web.ChannelCase do
   setup tags do
     :ok = Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
 
-    unless tags[:async] do
+    if tags[:async] do
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.NullCache)
+      Mox.set_mox_private()
+    else
       Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.CachexProxy)
+      Mox.set_mox_global()
+      Pleroma.DataCase.clear_cachex()
     end
 
     :ok
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index 47cb65a80..02f49c590 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -116,12 +116,16 @@ defmodule Pleroma.Web.ConnCase do
   end
 
   setup tags do
-    Cachex.clear(:user_cache)
-    Cachex.clear(:object_cache)
     :ok = Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
 
-    unless tags[:async] do
+    if tags[:async] do
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.NullCache)
+      Mox.set_mox_private()
+    else
       Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.CachexProxy)
+      Mox.set_mox_global()
+      Pleroma.DataCase.clear_cachex()
     end
 
     if tags[:needs_streamer] do
@@ -132,6 +136,8 @@ defmodule Pleroma.Web.ConnCase do
       })
     end
 
+    Pleroma.DataCase.stub_pipeline()
+
     {:ok, conn: Phoenix.ConnTest.build_conn()}
   end
 end
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index d5456521c..5c657c1d9 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -45,13 +45,34 @@ defmodule Pleroma.DataCase do
     end
   end
 
+  def clear_cachex do
+    Pleroma.Supervisor
+    |> Supervisor.which_children()
+    |> Enum.each(fn
+      {name, _, _, [Cachex]} ->
+        name
+        |> to_string
+        |> String.trim_leading("cachex_")
+        |> Kernel.<>("_cache")
+        |> String.to_existing_atom()
+        |> Cachex.clear()
+
+      _ ->
+        nil
+    end)
+  end
+
   setup tags do
-    Cachex.clear(:user_cache)
-    Cachex.clear(:object_cache)
     :ok = Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
 
-    unless tags[:async] do
+    if tags[:async] do
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.NullCache)
+      Mox.set_mox_private()
+    else
       Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
+      Mox.stub_with(Pleroma.CachexMock, Pleroma.CachexProxy)
+      Mox.set_mox_global()
+      clear_cachex()
     end
 
     if tags[:needs_streamer] do
@@ -62,9 +83,25 @@ defmodule Pleroma.DataCase do
       })
     end
 
+    stub_pipeline()
+
     :ok
   end
 
+  def stub_pipeline do
+    Mox.stub_with(Pleroma.Web.ActivityPub.SideEffectsMock, Pleroma.Web.ActivityPub.SideEffects)
+
+    Mox.stub_with(
+      Pleroma.Web.ActivityPub.ObjectValidatorMock,
+      Pleroma.Web.ActivityPub.ObjectValidator
+    )
+
+    Mox.stub_with(Pleroma.Web.ActivityPub.MRFMock, Pleroma.Web.ActivityPub.MRF)
+    Mox.stub_with(Pleroma.Web.ActivityPub.ActivityPubMock, Pleroma.Web.ActivityPub.ActivityPub)
+    Mox.stub_with(Pleroma.Web.FederatorMock, Pleroma.Web.Federator)
+    Mox.stub_with(Pleroma.ConfigMock, Pleroma.Config)
+  end
+
   def ensure_local_uploader(context) do
     test_uploader = Map.get(context, :uploader, Pleroma.Uploaders.Local)
     uploader = Pleroma.Config.get([Pleroma.Upload, :uploader])
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index 224034521..15e8cbd9d 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -55,6 +55,14 @@ defmodule Pleroma.Tests.Helpers do
           clear_config: 2
         ]
 
+      def time_travel(entity, seconds) do
+        new_time = NaiveDateTime.add(entity.inserted_at, seconds)
+
+        entity
+        |> Ecto.Changeset.change(%{inserted_at: new_time, updated_at: new_time})
+        |> Pleroma.Repo.update()
+      end
+
       def to_datetime(%NaiveDateTime{} = naive_datetime) do
         naive_datetime
         |> DateTime.from_naive!("Etc/UTC")
diff --git a/test/support/mocks.ex b/test/support/mocks.ex
new file mode 100644
index 000000000..a600a6458
--- /dev/null
+++ b/test/support/mocks.ex
@@ -0,0 +1,25 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+Mox.defmock(Pleroma.CachexMock, for: Pleroma.Caching)
+
+Mox.defmock(Pleroma.Web.ActivityPub.ObjectValidatorMock,
+  for: Pleroma.Web.ActivityPub.ObjectValidator.Validating
+)
+
+Mox.defmock(Pleroma.Web.ActivityPub.MRFMock,
+  for: Pleroma.Web.ActivityPub.MRF.PipelineFiltering
+)
+
+Mox.defmock(Pleroma.Web.ActivityPub.ActivityPubMock,
+  for: Pleroma.Web.ActivityPub.ActivityPub.Persisting
+)
+
+Mox.defmock(Pleroma.Web.ActivityPub.SideEffectsMock,
+  for: Pleroma.Web.ActivityPub.SideEffects.Handling
+)
+
+Mox.defmock(Pleroma.Web.FederatorMock, for: Pleroma.Web.Federator.Publishing)
+
+Mox.defmock(Pleroma.ConfigMock, for: Pleroma.Config.Getting)
diff --git a/test/support/null_cache.ex b/test/support/null_cache.ex
new file mode 100644
index 000000000..c63df6a39
--- /dev/null
+++ b/test/support/null_cache.ex
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.NullCache do
+  @moduledoc """
+  A module simulating a permanently empty cache.
+  """
+  @behaviour Pleroma.Caching
+
+  @impl true
+  def get!(_, _), do: nil
+
+  @impl true
+  def put(_, _, _, _ \\ nil), do: {:ok, true}
+
+  @impl true
+  def stream!(_, _), do: []
+
+  @impl true
+  def get(_, _), do: {:ok, nil}
+
+  @impl true
+  def fetch!(_, key, func) do
+    case func.(key) do
+      {_, res} -> res
+      res -> res
+    end
+  end
+
+  @impl true
+  def get_and_update(_, _, func) do
+    func.(nil)
+  end
+
+  @impl true
+  def expire_at(_, _, _), do: {:ok, true}
+
+  @impl true
+  def exists?(_, _), do: {:ok, false}
+
+  @impl true
+  def execute!(_, func) do
+    func.(:nothing)
+  end
+
+  @impl true
+  def del(_, _), do: {:ok, true}
+end