Maude 0.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Maude --version 0.2.0
                    
NuGet\Install-Package Maude -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Maude" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Maude" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Maude" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Maude --version 0.2.0
                    
#r "nuget: Maude, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Maude@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Maude&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Maude&version=0.2.0
                    
Install as a Cake Tool

Maude - In-app observability for .NET MAUI.

Maude is a plugin for .NET MAUI to monitor app memory at runtime and view it via live-rendered chart.

Maude, aka Maui-Debug, is a powerful, lightweight tool to help you in your debugging battles.

Disclaimer ⚠️

Best effort has been made for performance and correctness, but Maude continuously snapshots memory and stores recent samples in-memory; expect a small observer effect.

Please treat Maude’s numbers as a guidance, a heuristic.

Always use the native tools and platform specific profilers (Xcode Instruments, Android Studio profiler) or dotnet trace for authoritative measurements.

Quickstart

Add Maude to your MAUI app with minimal code.

  1. Configure the app builder:
// MauiProgram.cs
using Maude;

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder()
        .UseMauiApp<App>()
        .UseMaude<App>();  // Initialises and registers the Maude runtime.
    return builder.Build();
}
  1. Start tracking memory usage:
    MaudeRuntime.Activate();
  1. Show Maude:
// Show Maude as a slide in sheet.
MaudeRuntime.PresentSheet();   // Open the chart and events view as a slide in.
MaudeRuntime.DismissSheet();   // Close the slide in sheet.

// Show Maude as a window overlay.
MaudeRuntime.PresentOverlay();   // Show the chart as a window overlay.
MaudeRuntime.DismissOverlay();   // Close the overlay.

Record Events

Record markers and additional metrics so memory spikes have context.

// Define channels first (avoid reserved IDs 0, 1 and 255).
var channels = new []
{
    new MaudeChannel(96, "Image Cache", Colors.Orange),
    new MaudeChannel(97, "Network Buffers", Colors.Green)
};

// Initialise Maude with those channels.
var options = MaudeOptions.CreateBuilder()
    .WithAdditionalChannels(channels)
    .Build();
MaudeRuntime.InitializeAndActivate(options);

// Add metrics (rendered as extra series).
MaudeRuntime.Metric(currentCacheSizeBytes, 96);

// Add events (rendered as vertical markers + items in the event list).
MaudeRuntime.Event("Cache cleared", 96);                    // default type + icon "*"
MaudeRuntime.Event("GC requested", MaudeEventType.Gc);      // GC event symbol "g"
MaudeRuntime.Event("Large download", MaudeEventType.Event, 97, "42 MB");

Events/metrics on unknown channels are ignored. Both the slide-in sheet and overlay display the channels and event markers, letting you correlate spikes with the moments you annotated.

Customize Maude

Use the MaudeOptionsBuilder to tune sampling, channels, gestures and logging:

var options = MaudeOptions.CreateBuilder()
    .WithSampleFrequencyMilliseconds(500)     // clamp: 200–2000 ms
    .WithRetentionPeriodSeconds(10 * 60)      // clamp: 60–3600 s
    .WithAdditionalChannels(customChannels)   // extra metric/event series
    .WithShakeGesture()                       // enable shake-to-toggle
    .WithDefaultOverlayPosition(MaudeOverlayPosition.TopRight) // default anchor when showing overlay without an explicit position
    .WithShakeGestureBehaviour(MaudeShakeGestureBehaviour.Overlay) // or SlideSheet
    .WithEventRenderingBehaviour(MaudeEventRenderingBehaviour.IconsOnly) // LabelsAndIcons, IconsOnly (default), None
    .WithAdditionalLogger(new MyLogger())     // or .WithBuiltInLogger()
    .Build();

Use WithEventRenderingBehaviour (or adjust MaudeRuntime.EventRenderingBehaviour) to control whether the chart shows event icons with labels, icons only, or hides events. The selection applies to both the slide sheet and the overlay rendering modes.

Platform initialisation

While the MauiAppBuilder extension registers and initialises Maude, it may be desireable to ensure that Maude is sampling immediately when you're app starts.

To do so:

  • Android: initialise inside MainApplication so the runtime is ready before CreateMauiApp():
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
    : base(handle, ownership)
{
    var options = /* build options as above */;
    MaudeRuntime.InitializeAndActivate(options);
}
  • iOS/macOS Catalyst: initialise before UIApplication.Main in Program.cs:
var options = /* build options */;
MaudeRuntime.InitializeAndActivate(options);
UIApplication.Main(args, null, typeof(AppDelegate));

FPS Tracking

Maude can track frames-per-second in addition to memory usage, letting you correlate performance drops with allocations or GC pressure. Enable FPS sampling via the builder:

var options = MaudeOptions.CreateBuilder()
    .WithFramesPerSecond()
    .Build();

You can also toggle capture dynamically with MaudeRuntime.EnableFramesPerSecond() and .DisableFramesPerSecond(). The FPS line uses color-coded segments (Optimal, Stable, Fair, Poor, Critical) so slowdowns stand out even when you’re not looking at the numeric axis.

What does Maude capture?

Android

Metric Description + Documentation
Resident Set Size (RSS) Physical RAM currently mapped into the process (Java + native + runtime), excluding swapped pages. Android Memory Overview/proc reference
Native Heap Memory allocated through native allocators (malloc, new) used by the ART runtime and native libraries. Debug.getNativeHeapAllocatedSize
CLR (Managed Heap) Managed heap consumed by the .NET/Mono runtime (GC generations, LOH, objects, metadata). .NET GC Fundamentals

iOS

Metric Description + Documentation
Physical Footprint (Jetsam Footprint) Total physical RAM attributed to the process by the kernel — the metric Jetsam uses to terminate apps. task_vm_info_data_tWWDC Memory Deep Dive
Available Headroom Approximate remaining memory the process can consume before triggering Jetsam pressure. os_proc_available_memory source
CLR (Managed Heap) Managed memory used by the .NET/Mono runtime on iOS (AOT GC heap + metadata). .NET GC Fundamentals

Limitations and Known Issues

MAUI’s WindowOverlay attaches to the root window, so modal pages can obscure the overlay. Use the slide-in sheet (Present) for modal-heavy flows.

Target framework

Maude is explicitly built for .NET 9+ to leverage Span<T> optimisations and MAUI native embedding; earlier target frameworks are unsupported.

Product Compatible and additional computed target framework versions.
.NET net9.0-android35.0 is compatible.  net9.0-ios18.0 is compatible.  net10.0-android was computed.  net10.0-ios was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 293 2/9/2026
0.3.0-pre1 505 12/8/2025
0.2.0 5,489 11/23/2025
0.2.0-pre3 406 11/20/2025
0.2.0-pre2 396 11/19/2025
0.2.0-pre 401 11/19/2025
0.1.0 392 11/17/2025
0.1.0-pre2 309 11/17/2025
0.1.0-pre 308 11/17/2025