From 9303956e0c677587cffa752dec03b7e4c25d31eb Mon Sep 17 00:00:00 2001
From: Daniel Doehring <daniel.doehring@rwth-aachen.de>
Date: Tue, 24 Oct 2023 16:29:22 +0200
Subject: [PATCH] Allocation tests (#1687)

* Passing allocation tests

* Passing tests

* Update tests

* add check for coverage

* more tests

* more tests

* comments

---------

Co-authored-by: Hendrik Ranocha <ranocha@users.noreply.github.com>
---
 test/test_p4est_2d.jl                         | 184 +++++++++-
 ...est_paper_self_gravitating_gas_dynamics.jl | 104 ++++++
 test/test_structured_2d.jl                    | 336 +++++++++++++++++-
 test/test_tree_1d_hypdiff.jl                  |  16 +
 test/test_tree_2d_advection.jl                | 154 +++++++-
 test/test_tree_2d_hypdiff.jl                  |  32 ++
 test/test_tree_2d_kpp.jl                      |  19 +-
 test/test_tree_3d_hypdiff.jl                  |  24 ++
 8 files changed, 828 insertions(+), 41 deletions(-)

diff --git a/test/test_p4est_2d.jl b/test/test_p4est_2d.jl
index 31dfe1d35a5..5baa090c8d7 100644
--- a/test/test_p4est_2d.jl
+++ b/test/test_p4est_2d.jl
@@ -17,27 +17,42 @@ isdir(outdir) && rm(outdir, recursive=true)
       # Expected errors are exactly the same as with TreeMesh!
       l2   = [8.311947673061856e-6],
       linf = [6.627000273229378e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_nonconforming_flag.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_nonconforming_flag.jl"),
       l2   = [3.198940059144588e-5],
       linf = [0.00030636069494005547])
-
-    # Ensure that we do not have excessive memory allocations
-    # (e.g., from type instabilities)
-    let
-      t = sol.t[end]
-      u_ode = sol.u[end]
-      du_ode = similar(u_ode)
-      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_unstructured_flag.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_unstructured_flag.jl"),
       l2   = [0.0005379687442422346],
       linf = [0.007438525029884735])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_amr_solution_independent.jl" begin
@@ -46,6 +61,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [4.949660644033807e-5],
       linf = [0.0004867846262313763],
       coverage_override = (maxiters=6,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_amr_unstructured_flag.jl" begin
@@ -53,18 +76,42 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.0012766060609964525],
       linf = [0.01750280631586159],
       coverage_override = (maxiters=6,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_restart.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_restart.jl"),
       l2   = [4.507575525876275e-6],
       linf = [6.21489667023134e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_source_terms_nonconforming_unstructured_flag.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_nonconforming_unstructured_flag.jl"),
     l2   = [0.0034516244508588046, 0.0023420334036925493, 0.0024261923964557187, 0.004731710454271893],
     linf = [0.04155789011775046, 0.024772109862748914, 0.03759938693042297, 0.08039824959535657])
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_euler_free_stream.jl" begin
@@ -73,6 +120,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [1.9539925233402755e-14, 2e-12, 4.8e-12, 4e-12],
       atol = 2.0e-12, # required to make CI tests pass on macOS
     )
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_euler_shockcapturing_ec.jl" begin
@@ -80,6 +135,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [9.53984675e-02, 1.05633455e-01, 1.05636158e-01, 3.50747237e-01],
       linf = [2.94357464e-01, 4.07893014e-01, 3.97334516e-01, 1.08142520e+00],
       tspan = (0.0, 1.0))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_sedov.jl" begin
@@ -87,6 +150,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [3.76149952e-01, 2.46970327e-01, 2.46970327e-01, 1.28889042e+00],
       linf = [1.22139001e+00, 1.17742626e+00, 1.17742626e+00, 6.20638482e+00],
       tspan = (0.0, 0.3))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_blast_wave_amr.jl" begin
@@ -95,6 +166,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [2.76020890e+00, 2.32659890e+00, 2.32580837e+00, 2.15778188e+00],
       tspan = (0.0, 0.3),
       coverage_override = (maxiters=6,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_wall_bc_amr.jl" begin
@@ -102,15 +181,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.020291447969983396, 0.017479614254319948, 0.011387644425613437, 0.0514420126021293],
       linf = [0.3582779022370579, 0.32073537890751663, 0.221818049107692, 0.9209559420400415],
       tspan = (0.0, 0.15))
-
-    # Ensure that we do not have excessive memory allocations
-    # (e.g., from type instabilities)
-    let
-      t = sol.t[end]
-      u_ode = sol.u[end]
-      du_ode = similar(u_ode)
-      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_forward_step_amr.jl" begin
@@ -120,6 +198,16 @@ isdir(outdir) && rm(outdir, recursive=true)
       tspan = (0.0, 0.0001),
       rtol = 1.0e-7,
       skip_coverage=true)
+      if @isdefined sol # Skipped in coverage run
+        # Ensure that we do not have excessive memory allocations 
+        # (e.g., from type instabilities) 
+        let 
+          t = sol.t[end] 
+          u_ode = sol.u[end] 
+          du_ode = similar(u_ode) 
+          @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+        end
+      end
   end
 
   @trixi_testset "elixir_euler_double_mach_amr.jl" begin
@@ -128,6 +216,16 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [6.902000373057003, 53.95714139820832, 24.241610279839758, 561.0630401858057],
       tspan = (0.0, 0.0001),
       skip_coverage=true)
+      if @isdefined sol # Skipped in coverage run
+        # Ensure that we do not have excessive memory allocations 
+        # (e.g., from type instabilities) 
+        let 
+          t = sol.t[end] 
+          u_ode = sol.u[end] 
+          du_ode = similar(u_ode) 
+          @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+        end
+      end
   end
 
   @trixi_testset "elixir_euler_supersonic_cylinder.jl" begin
@@ -136,6 +234,16 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [3.653905721692421, 4.285035711361009, 6.8544353186357645, 31.748244912257533],
       tspan = (0.0, 0.001),
       skip_coverage=true)
+      if @isdefined sol # Skipped in coverage run
+        # Ensure that we do not have excessive memory allocations 
+        # (e.g., from type instabilities) 
+        let 
+          t = sol.t[end] 
+          u_ode = sol.u[end] 
+          du_ode = similar(u_ode) 
+          @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+        end
+      end
   end
 
   @trixi_testset "elixir_eulergravity_convergence.jl" begin
@@ -143,6 +251,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.00024871265138964204, 0.0003370077102132591, 0.0003370077102131964, 0.0007231525513793697],
       linf = [0.0015813032944647087, 0.0020494288423820173, 0.0020494288423824614, 0.004793821195083758],
       tspan = (0.0, 0.1))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_source_terms.jl" begin
@@ -150,6 +266,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [9.168126407325352e-5, 0.0009795410115453788, 0.002546408320320785, 3.941189812642317e-6],
       linf = [0.0009903782521019089, 0.0059752684687262025, 0.010941106525454103, 1.2129488214718265e-5],
       tspan = (0.0, 0.1))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_mhd_alfven_wave.jl" begin
@@ -160,6 +284,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [4.255466285174592e-5, 1.0029706745823264e-5, 1.0029706747467781e-5, 1.2122265939010224e-5,
               5.4791097160444835e-6, 5.18922042269665e-6, 5.189220422141538e-6, 9.552667261422676e-6,
               1.4237578427628152e-6])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_mhd_rotor.jl" begin
@@ -171,12 +303,28 @@ isdir(outdir) && rm(outdir, recursive=true)
               19.647239392277378, 1.3938810140985936, 1.8724965294853084, 0.0,
               0.0016290067532561904],
       tspan = (0.0, 0.02))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_linearizedeuler_gaussian_source.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_linearizedeuler_gaussian_source.jl"),
       l2 = [0.006047938590548741, 0.0040953286019907035, 0.004222698522497298, 0.006269492499336128],
       linf = [0.06386175207349379, 0.0378926444850457, 0.041759728067967065, 0.06430136016259067])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 end
 
diff --git a/test/test_paper_self_gravitating_gas_dynamics.jl b/test/test_paper_self_gravitating_gas_dynamics.jl
index 6a35543fe47..68aa2992601 100644
--- a/test/test_paper_self_gravitating_gas_dynamics.jl
+++ b/test/test_paper_self_gravitating_gas_dynamics.jl
@@ -17,6 +17,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_convergence.jl"),
       l2   = [0.0001740977055972079, 0.0003369355182519592, 0.0003369355182518708, 0.0006099171220334989],
       linf = [0.001079347149189669, 0.0018836938381321389, 0.001883693838132583, 0.003971575376718217])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_convergence.jl with polydeg=4" begin
@@ -24,6 +32,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [1.7187201161597772e-5, 2.678065111772951e-5, 2.678065111783027e-5, 4.952504160091526e-5],
       linf = [0.0001501749544159381, 0.00016549482504535362, 0.00016549482504601976, 0.0004372960291432193],
       polydeg = 4)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
 
@@ -31,6 +47,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_hypdiff_convergence.jl"),
       l2   = [0.003154024896093942, 0.012394432074951856, 0.02185973823794725],
       linf = [0.01731850928579215, 0.07843510773347553, 0.11242300176349201])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_convergence.jl with polydeg=4" begin
@@ -38,6 +62,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [0.0002511283012128458, 0.0008808243846610255, 0.0016313343228567005],
       linf = [0.0017290715087938668, 0.003129184465704738, 0.01000728849316701],
       polydeg = 4)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
 
@@ -46,6 +78,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [0.00024871265138964204, 0.0003370077102132591, 0.0003370077102131964, 0.0007231525513793697],
       linf = [0.0015813032944647087, 0.0020494288423820173, 0.0020494288423824614, 0.004793821195083758],
       tspan = (0.0, 0.1))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulergravity_convergence.jl with polydeg=4" begin
@@ -53,6 +93,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [1.9537712148648045e-5, 2.7564396197947587e-5, 2.7564396197967635e-5, 5.688838772067586e-5],
       linf = [0.00012335710672761735, 0.00020086268350816283, 0.00020086268350727465, 0.0004962155455632278],
       tspan = (0.0, 0.1), polydeg = 4)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulergravity_convergence.jl with 1st order RK3S*" begin
@@ -60,6 +108,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [0.00024871265138959434, 0.000337007710281087, 0.0003370077102811394, 0.0007231525515231289],
       linf = [0.0015813032941613958, 0.002049428843978518, 0.0020494288439798503, 0.004793821198143977],
       tspan = (0.0, 0.1), timestep_gravity=Trixi.timestep_gravity_erk51_3Sstar!)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulergravity_convergence.jl with 3rd order RK3S*" begin
@@ -67,6 +123,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [0.0002487126513894034, 0.00033700771023049785, 0.00033700771023048245, 0.0007231525514158737],
       linf = [0.0015813032943847727, 0.002049428842844314, 0.0020494288428452023, 0.004793821195971937],
       tspan = (0.0, 0.1), timestep_gravity=Trixi.timestep_gravity_erk53_3Sstar!)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
 
@@ -77,6 +141,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       tspan = (0.0, 0.1),
       atol = 4.0e-6 # the background field is reatively large, so this corresponds to our usual atol
       )
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulergravity_jeans_instability.jl with RK3S*" begin
@@ -91,6 +163,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
                                         resid_tol=1.0e-4,
                                         n_iterations_max=1000,
                                         timestep_gravity=timestep_gravity_erk52_3Sstar!))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "Printing" begin
@@ -108,6 +188,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
     show(stdout, semi_euler.boundary_conditions)
     show(stdout, TrivialCallback())
     show(stdout, equations_euler)
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
 
@@ -117,6 +205,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       linf = [2.3874843337593776, 4.07876384374792, 4.07876384374792, 16.23914384809855],
       tspan = (0.0, 0.05),
       coverage_override = (maxiters=2,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulergravity_sedov_blast_wave.jl with ref-level=8 and no AMR" begin
@@ -124,6 +220,14 @@ const EXAMPLES_DIR = pkgdir(Trixi, "examples", "paper_self_gravitating_gas_dynam
       l2   = [0.00289222135995042, 0.013724813590853825, 0.013724813590853832, 0.05822904710548214],
       linf = [0.26361780693997594, 1.3908873830688688, 1.3908873830688688, 4.066701303607613],
       tspan = (0.0, 0.005), initial_refinement_level=8, amr_callback=TrivialCallback())
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 end
 
diff --git a/test/test_structured_2d.jl b/test/test_structured_2d.jl
index 6d528abc7af..c3192f52b2c 100644
--- a/test/test_structured_2d.jl
+++ b/test/test_structured_2d.jl
@@ -19,6 +19,15 @@ isdir(outdir) && rm(outdir, recursive=true)
       # Expected errors are exactly the same as with TreeMesh!
       l2   = [8.311947673061856e-6],
       linf = [6.627000273229378e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
+    end
   end
 
   @trixi_testset "elixir_advection_coupled.jl" begin
@@ -31,6 +40,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       errors = analysis_callback(sol)
       @test errors.l2   ≈ [7.816742843181738e-6, 7.816742843196112e-6] rtol=1.0e-4
       @test errors.linf ≈ [6.314906965543265e-5, 6.314906965410039e-5] rtol=1.0e-4
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
     end
   end
 
@@ -38,6 +55,14 @@ isdir(outdir) && rm(outdir, recursive=true)
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_extended.jl"),
       l2   = [4.220397559713772e-6],
       linf = [3.477948874874848e-5])
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_advection_extended.jl with polydeg=4" begin
@@ -48,6 +73,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       cells_per_dimension = (16, 23),
       polydeg = 4,
       cfl = 1.4)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @testset "elixir_advection_rotated.jl" begin
@@ -57,6 +90,14 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [8.311947673061856e-6],
         linf = [6.627000273229378e-5],
         alpha = 0.0)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
     end
 
     @trixi_testset "elixir_advection_rotated.jl with α = 0.1" begin
@@ -65,6 +106,14 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [8.3122750550501e-6],
         linf = [6.626802581322089e-5],
         alpha = 0.1)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
     end
 
     @trixi_testset "elixir_advection_rotated.jl with α = 0.5 * pi" begin
@@ -73,6 +122,14 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [8.311947673061856e-6],
         linf = [6.627000273229378e-5],
         alpha = 0.5 * pi)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
     end
   end
 
@@ -81,30 +138,70 @@ isdir(outdir) && rm(outdir, recursive=true)
       # Expected errors are exactly the same as in elixir_advection_basic!
       l2   = [8.311947673061856e-6],
       linf = [6.627000273229378e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_waving_flag.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_waving_flag.jl"),
       l2   = [0.00018553859900545866],
       linf = [0.0016167719118129753])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_free_stream.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_free_stream.jl"),
       l2   = [6.8925194184204476e-15],
       linf = [9.903189379656396e-14])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_nonperiodic.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_nonperiodic.jl"),
       l2   = [0.00025552740731641223],
       linf = [0.007252625722805939])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_restart.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_restart.jl"),
       l2   = [4.219208035582454e-6],
       linf = [3.438434404412494e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_restart.jl with waving flag mesh" begin
@@ -114,6 +211,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       rtol = 5.0e-5, # Higher tolerance to make tests pass in CI (in particular with macOS)
       elixir_file="elixir_advection_waving_flag.jl",
       restart_file="restart_000021.h5")
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_restart.jl with free stream mesh" begin
@@ -122,6 +227,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [1.0857981180834031e-13],
       elixir_file="elixir_advection_free_stream.jl",
       restart_file="restart_000036.h5")
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_source_terms.jl" begin
@@ -129,6 +242,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       # Expected errors are exactly the same as with TreeMesh!
       l2   = [9.321181253186009e-7, 1.4181210743438511e-6, 1.4181210743487851e-6, 4.824553091276693e-6],
       linf = [9.577246529612893e-6, 1.1707525976012434e-5, 1.1707525976456523e-5, 4.8869615580926506e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @testset "elixir_euler_source_terms_rotated.jl" begin
@@ -138,7 +259,15 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [9.321181253186009e-7, 1.4181210743438511e-6, 1.4181210743487851e-6, 4.824553091276693e-6],
         linf = [9.577246529612893e-6, 1.1707525976012434e-5, 1.1707525976456523e-5, 4.8869615580926506e-5],
         alpha = 0.0)
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
+  end
 
     @trixi_testset "elixir_euler_source_terms_rotated.jl with α = 0.1" begin
       @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_rotated.jl"),
@@ -146,7 +275,15 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [9.321188057029291e-7, 1.3195106906473365e-6, 1.510307360354032e-6, 4.82455408101712e-6],
         linf = [9.57723626271445e-6, 1.0480225511866337e-5, 1.2817828088262928e-5, 4.886962393513272e-5],
         alpha = 0.1)
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
+  end
 
     @trixi_testset "elixir_euler_source_terms_rotated.jl with α = 0.2 * pi" begin
       @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_rotated.jl"),
@@ -154,7 +291,15 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [9.32127973957391e-7, 8.477824799744325e-7, 1.8175286311402784e-6, 4.824562453521076e-6],
         linf = [9.576898420737834e-6, 5.057704352218195e-6, 1.635260719945464e-5, 4.886978754825577e-5],
         alpha = 0.2 * pi)
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
+  end
 
     @trixi_testset "elixir_euler_source_terms_rotated.jl with α = 0.5 * pi" begin
       @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_rotated.jl"),
@@ -162,19 +307,42 @@ isdir(outdir) && rm(outdir, recursive=true)
         l2   = [9.321181253186009e-7, 1.4181210743438511e-6, 1.4181210743487851e-6, 4.824553091276693e-6],
         linf = [9.577246529612893e-6, 1.1707525976012434e-5, 1.1707525976456523e-5, 4.8869615580926506e-5],
         alpha = 0.5 * pi)
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_source_terms_parallelogram.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_parallelogram.jl"),
       l2   = [1.1167802955144833e-5, 1.0805775514153104e-5, 1.953188337010932e-5, 5.5033856574857146e-5],
       linf = [8.297006495561199e-5, 8.663281475951301e-5, 0.00012264160606778596, 0.00041818802502024965])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_source_terms_waving_flag.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_waving_flag.jl"),
       l2   = [2.991891317562739e-5, 3.6063177168283174e-5, 2.7082941743640572e-5, 0.00011414695350996946],
       linf = [0.0002437454930492855, 0.0003438936171968887, 0.00024217622945688078, 0.001266380414757684])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_free_stream.jl" begin
@@ -182,6 +350,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [2.063350241405049e-15, 1.8571016296925367e-14, 3.1769447886391905e-14, 1.4104095258528071e-14],
       linf = [1.9539925233402755e-14, 2.9791447087035294e-13, 6.502853810985698e-13, 2.7000623958883807e-13],
       atol = 7.0e-13)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_free_stream.jl with FluxRotated(flux_lax_friedrichs)" begin
@@ -190,12 +366,28 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [2.063350241405049e-15, 1.8571016296925367e-14, 3.1769447886391905e-14, 1.4104095258528071e-14],
       linf = [1.9539925233402755e-14, 2.9791447087035294e-13, 6.502853810985698e-13, 2.7000623958883807e-13],
       atol = 7.0e-13)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_source_terms_nonperiodic.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_euler_source_terms_nonperiodic.jl"),
       l2   = [2.259440511901724e-6, 2.3188881559075347e-6, 2.3188881559568146e-6, 6.332786324137878e-6],
       linf = [1.4987382622067003e-5, 1.918201192063762e-5, 1.918201192019353e-5, 6.052671713430158e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_ec.jl" begin
@@ -203,6 +395,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.03774907669925568, 0.02845190575242045, 0.028262802829412605, 0.13785915638851698],
       linf = [0.3368296929764073, 0.27644083771519773, 0.27990039685141377, 1.1971436487402016],
       tspan = (0.0, 0.3))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_sedov.jl" begin
@@ -210,6 +410,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [3.69856202e-01, 2.35242180e-01, 2.41444928e-01, 1.28807120e+00],
       linf = [1.82786223e+00, 1.30452904e+00, 1.40347257e+00, 6.21791658e+00],
       tspan = (0.0, 0.3))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_euler_rayleigh_taylor_instability.jl" begin
@@ -218,30 +426,70 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [0.4799214336153155, 0.024595483032220266, 0.02059808120543466, 0.03190756362943725],
       cells_per_dimension = (8,8),
       tspan = (0.0, 0.3))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulerpolytropic_convergence.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_eulerpolytropic_convergence.jl"),
       l2   = [0.0016688820596537988, 0.0025921681885685425, 0.003280950351435014],
       linf = [0.010994679664394269, 0.01331197845637, 0.020080117011346488])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulerpolytropic_ec.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_eulerpolytropic_ec.jl"),
       l2   = [0.03647890611450939, 0.025284915444045052, 0.025340697771609126],
       linf = [0.32516731565355583, 0.37509762516540046, 0.29812843284727336])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulerpolytropic_isothermal_wave.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_eulerpolytropic_isothermal_wave.jl"),
       l2   = [0.004998778491726366, 0.004998916000294425, 9.259136963058664e-17],
       linf = [0.010001103673834888, 0.010051165098399503, 7.623942913643681e-16])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_eulerpolytropic_wave.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_eulerpolytropic_wave.jl"),
       l2   = [0.23642682112204072, 0.20904264390331334, 8.174982691297391e-17],
       linf = [0.4848250368349989, 0.253350873815695, 4.984552457753618e-16])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_nonperiodic.jl" begin
@@ -250,6 +498,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [1.0771947577311836, 1.9143913544309838, 2.149549109115789],
       tspan = (0.0, 0.1),
       coverage_override = (polydeg=3,)) # Prevent long compile time in CI
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_harmonic_nonperiodic.jl" begin
@@ -258,6 +514,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [0.35026352556630114, 0.8344372248051408, 0.8344372248051408],
       tspan = (0.0, 0.1),
       coverage_override = (polydeg=3,)) # Prevent long compile time in CI
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_mhd_ec.jl" begin
@@ -269,6 +533,14 @@ isdir(outdir) && rm(outdir, recursive=true)
               0.9757376320946505, 0.12123736788315098, 0.12837436699267113, 0.17793825293524734,
               0.03460761690059514],
       tspan = (0.0, 0.3))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_mhd_alfven_wave.jl" begin
@@ -280,6 +552,14 @@ isdir(outdir) && rm(outdir, recursive=true)
               0.03817506476831778, 0.042847170999492534, 0.03761563456810613, 0.048184237474911844,
               0.04114666955364693],
       tspan = (0.0, 1.0))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_source_terms.jl" begin
@@ -287,6 +567,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.0017285599436729316, 0.025584610912606776, 0.028373834961180594, 6.274146767730866e-5],
       linf = [0.012972309788264802, 0.108283714215621, 0.15831585777928936, 0.00018196759554722775],
       tspan = (0.0, 0.05))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_well_balanced.jl" begin
@@ -294,6 +582,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.7920927046419308, 9.92129670988898e-15, 1.0118635033124588e-14, 0.7920927046419308],
       linf = [2.408429868800133, 5.5835419986809516e-14, 5.448874313931364e-14, 2.4084298688001335],
       tspan = (0.0, 0.25))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_well_balanced_wet_dry.jl" begin
@@ -301,6 +597,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.019731646454942086, 1.0694532773278277e-14, 1.1969913383405568e-14, 0.0771517260037954],
       linf = [0.4999999999998892, 6.067153702623552e-14, 4.4849667259339357e-14, 1.9999999999999993],
       tspan = (0.0, 0.25))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_conical_island.jl" begin
@@ -308,6 +612,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.04593154164306353, 0.1644534881916908, 0.16445348819169076, 0.0011537702354532122],
       linf = [0.21100717610846442, 0.9501592344310412, 0.950159234431041, 0.021790250683516296],
       tspan = (0.0, 0.025))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_shallowwater_parabolic_bowl.jl" begin
@@ -315,6 +627,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       l2   = [0.00015285369980313484, 1.9536806395943226e-5, 9.936906607758672e-5, 5.0686313334616055e-15],
       linf = [0.003316119030459211, 0.0005075409427972817, 0.001986721761060583, 4.701794509287538e-14],
       tspan = (0.0, 0.025), cells_per_dimension = (40, 40))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_mhd_ec_shockcapturing.jl" begin
@@ -325,6 +645,14 @@ isdir(outdir) && rm(outdir, recursive=true)
       linf = [0.25144373906033013, 0.32881947152723745, 0.3053266801502693, 0.20989755319972866,
               0.9927517314507455, 0.1105172121361323, 0.1257708104676617, 0.1628334844841588,
               0.02624301627479052])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 end
 
diff --git a/test/test_tree_1d_hypdiff.jl b/test/test_tree_1d_hypdiff.jl
index 560f77b2a13..19200b26892 100644
--- a/test/test_tree_1d_hypdiff.jl
+++ b/test/test_tree_1d_hypdiff.jl
@@ -14,6 +14,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_1d_dgsem")
       l2   = [1.3655114954641076e-7, 1.0200345025539218e-6],
       linf = [7.173286515893551e-7, 4.507116363683394e-6],
       atol = 2.5e-13)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_harmonic_nonperiodic.jl" begin
@@ -21,6 +29,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_1d_dgsem")
       l2   = [3.0130941075207524e-12, 2.6240829677090014e-12],
       linf = [4.054534485931072e-12, 3.8826719617190975e-12],
       atol = 2.5e-13)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 10000
+      end
   end
 end
 
diff --git a/test/test_tree_2d_advection.jl b/test/test_tree_2d_advection.jl
index 36cb1e882cc..365011eef53 100644
--- a/test/test_tree_2d_advection.jl
+++ b/test/test_tree_2d_advection.jl
@@ -15,6 +15,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       linf = [6.627000273229378e-5],
       # Let the small basic test run to the end
       coverage_override = (maxiters=10^5,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_extended.jl with polydeg=1" begin
@@ -22,6 +30,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [0.02134571266411136],
       linf = [0.04347734797775926],
       polydeg=1)
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_advection_restart.jl" begin
@@ -49,14 +65,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [0.0015188466707237375],
       linf = [0.008446655719187679])
 
-    # Ensure that we do not have excessive memory allocations
-    # (e.g., from type instabilities)
-    let
-      t = sol.t[end]
-      u_ode = sol.u[end]
-      du_ode = similar(u_ode)
-      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
-    end
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_amr.jl" begin
@@ -66,6 +82,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       linf = [0.00045263895394385967],
       # Let this test run to the end to cover some AMR code
       coverage_override = (maxiters=10^5,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_amr_nonperiodic.jl" begin
@@ -74,6 +98,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [3.2207388565869075e-5],
       linf = [0.0007508059772436404],
       coverage_override = (maxiters=6,))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_amr_solution_independent.jl" begin
@@ -81,6 +113,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [4.949660644033807e-5],
       linf = [0.0004867846262313763],
       coverage_override = (maxiters=6,))
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_advection_amr_visualization.jl" begin
@@ -114,6 +154,15 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       # Let this test terminate by time instead of maxiters to cover some lines
       # in time_integration/methods_2N.jl
       coverage_override = (maxiters=10^5, tspan=(0.0, 0.1)))
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
+    end
   end
 
   @trixi_testset "elixir_advection_timeintegration.jl with carpenter_kennedy_erk43" begin
@@ -122,6 +171,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       linf = [0.0005437136621948904],
       ode_algorithm=Trixi.CarpenterKennedy2N43(),
       cfl = 1.0)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_advection_timeintegration.jl with carpenter_kennedy_erk43 with maxiters=1" begin
@@ -131,6 +188,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       ode_algorithm=Trixi.CarpenterKennedy2N43(),
       cfl = 1.0,
       maxiters = 1)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_advection_timeintegration.jl with parsani_ketcheson_deconinck_erk94" begin
@@ -138,6 +203,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [2.4976673477385313e-5],
       linf = [0.0005534166916640881],
       ode_algorithm=Trixi.ParsaniKetchesonDeconinck3Sstar94())
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_advection_timeintegration.jl with parsani_ketcheson_deconinck_erk32" begin
@@ -146,6 +219,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       linf = [0.0005799465470165757],
       ode_algorithm=Trixi.ParsaniKetchesonDeconinck3Sstar32(),
       cfl = 1.0)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_advection_timeintegration.jl with parsani_ketcheson_deconinck_erk32 with maxiters=1" begin
@@ -155,14 +236,29 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       ode_algorithm=Trixi.ParsaniKetchesonDeconinck3Sstar32(),
       cfl = 1.0,
       maxiters = 1)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_advection_callbacks.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_advection_callbacks.jl"),
       l2   = [8.311947673061856e-6],
       linf = [6.627000273229378e-5])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
-end
 
 # Coverage test for all initial conditions
 @testset "Linear scalar advection: Tests for initial conditions" begin
@@ -173,6 +269,14 @@ end
       linf = [0.0007140570281718439],
       maxiters = 1,
       initial_condition = Trixi.initial_condition_sin_sin)
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_advection_extended.jl with initial_condition_constant" begin
@@ -181,6 +285,14 @@ end
       linf = [1.3322676295501878e-15],
       maxiters = 1,
       initial_condition = initial_condition_constant)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_extended.jl with initial_condition_linear_x_y" begin
@@ -191,6 +303,14 @@ end
       initial_condition = Trixi.initial_condition_linear_x_y,
       boundary_conditions = Trixi.boundary_condition_linear_x_y,
       periodicity=false)
+    # Ensure that we do not have excessive memory allocations 
+    # (e.g., from type instabilities) 
+    let 
+      t = sol.t[end] 
+      u_ode = sol.u[end] 
+      du_ode = similar(u_ode) 
+      @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+    end
   end
 
   @trixi_testset "elixir_advection_extended.jl with initial_condition_linear_x" begin
@@ -201,6 +321,14 @@ end
       initial_condition = Trixi.initial_condition_linear_x,
       boundary_conditions = Trixi.boundary_condition_linear_x,
       periodicity=false)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_advection_extended.jl with initial_condition_linear_y" begin
@@ -211,6 +339,14 @@ end
       initial_condition = Trixi.initial_condition_linear_y,
       boundary_conditions = Trixi.boundary_condition_linear_y,
       periodicity=false)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 end
 
diff --git a/test/test_tree_2d_hypdiff.jl b/test/test_tree_2d_hypdiff.jl
index eb8f8b297b6..30481fe910a 100644
--- a/test/test_tree_2d_hypdiff.jl
+++ b/test/test_tree_2d_hypdiff.jl
@@ -12,18 +12,42 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_hypdiff_lax_friedrichs.jl"),
       l2   = [0.00015687751817403066, 0.001025986772216324, 0.0010259867722164071],
       linf = [0.001198695637957381, 0.006423873515531753, 0.006423873515533529])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_harmonic_nonperiodic.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_hypdiff_harmonic_nonperiodic.jl"),
       l2   = [8.618132355121019e-8, 5.619399844384306e-7, 5.619399844844044e-7],
       linf = [1.1248618588430072e-6, 8.622436487026874e-6, 8.622436487915053e-6])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_nonperiodic.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_hypdiff_nonperiodic.jl"),
       l2   = [8.523077653954864e-6, 2.8779323653020624e-5, 5.454942769125663e-5],
       linf = [5.522740952468297e-5, 0.00014544895978971679, 0.00032396328684924924])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_godunov.jl" begin
@@ -31,6 +55,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_2d_dgsem")
       l2   = [5.868147556427088e-6, 3.80517927324465e-5, 3.805179273249344e-5],
       linf = [3.701965498725812e-5, 0.0002122422943138247, 0.00021224229431116015],
       atol = 2.0e-12 #= required for CI on macOS =#)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000 
+      end
   end
 end
 
diff --git a/test/test_tree_2d_kpp.jl b/test/test_tree_2d_kpp.jl
index 16d240d4a9f..fb2a212ddf8 100644
--- a/test/test_tree_2d_kpp.jl
+++ b/test/test_tree_2d_kpp.jl
@@ -17,17 +17,16 @@ EXAMPLES_DIR = joinpath(examples_dir(), "tree_2d_dgsem")
       atol = 1e-6,
       rtol = 1e-6,
       skip_coverage = true)
-
-      #= Does fail in coverage run (since it is not executed)
-      # Ensure that we do not have excessive memory allocations
-      # (e.g., from type instabilities)
-      let
-        t = sol.t[end]
-        u_ode = sol.u[end]
-        du_ode = similar(u_ode)
-        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
+      if @isdefined sol # Skipped in coverage run
+        # Ensure that we do not have excessive memory allocations
+        # (e.g., from type instabilities)
+        let
+          t = sol.t[end]
+          u_ode = sol.u[end]
+          du_ode = similar(u_ode)
+          @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 1000
+        end
       end
-      =#
   end
 end
 
diff --git a/test/test_tree_3d_hypdiff.jl b/test/test_tree_3d_hypdiff.jl
index 3db0ce93186..42231a9aaf6 100644
--- a/test/test_tree_3d_hypdiff.jl
+++ b/test/test_tree_3d_hypdiff.jl
@@ -13,6 +13,14 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_3d_dgsem")
       l2   = [0.001530331609036682, 0.011314177033289238, 0.011314177033289402, 0.011314177033289631],
       linf = [0.02263459033909354, 0.10139777904683545, 0.10139777904683545, 0.10139777904683545],
       initial_refinement_level=2)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_lax_friedrichs.jl with surface_flux=flux_godunov)" begin
@@ -20,12 +28,28 @@ EXAMPLES_DIR = pkgdir(Trixi, "examples", "tree_3d_dgsem")
       l2   = [0.0015377731806850128, 0.01137685274151801, 0.011376852741518175, 0.011376852741518494],
       linf = [0.022715420630041172, 0.10183745338964201, 0.10183745338964201, 0.1018374533896429],
       initial_refinement_level=2, surface_flux=flux_godunov)
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 
   @trixi_testset "elixir_hypdiff_nonperiodic.jl" begin
     @test_trixi_include(joinpath(EXAMPLES_DIR, "elixir_hypdiff_nonperiodic.jl"),
       l2   = [0.00022868320512754316, 0.0007974309948540525, 0.0015035143230654987, 0.0015035143230655293],
       linf = [0.0016405001653623241, 0.0029870057159104594, 0.009410031618285686, 0.009410031618287462])
+      # Ensure that we do not have excessive memory allocations 
+      # (e.g., from type instabilities) 
+      let 
+        t = sol.t[end] 
+        u_ode = sol.u[end] 
+        du_ode = similar(u_ode) 
+        @test (@allocated Trixi.rhs!(du_ode, u_ode, semi, t)) < 15000 
+      end
   end
 end