Profiling des Forge-App-Speichers zur Reduzierung der Rechenkosten

Dr. Shu Shen
January 7, 2026

Da Atlassian Forge 2026 offiziell auf ein verbrauchsorientiertes Preismodell umgestellt hat, ist Effizienz heute eine zentrale technische Anforderung. Im Rahmen des neuen Modells hängen die Kosten deiner App direkt davon ab GB-Sekunden: das Produkt aus Ihrer Ausführungszeit und Ihrem zugewiesenen Speicher.

Während die Ausführungszeit oft im Mittelpunkt der Optimierung steht, Speicherzuweisung ist ein ebenso wichtiger Hebel zur Kostenkontrolle. Viele Entwickler lassen ihre Apps im Standardeinstellung 512 MB, was im Wesentlichen für „leere Luft“ bezahlt.

Durch die Erstellung von Profilen zur tatsächlichen Speichernutzung können Sie Ihre Speicherzuweisungen sicher reduzieren und unser Geschäftsergebnis schützen.

Warum die Speicherzuweisung für Ihre Rechnung wichtig ist

Da die Laufzeit von Forge auf einer serverlosen Infrastruktur basiert, gelten auch hier die wirtschaftlichen Prinzipien von AWS Lambda. A aktueller Artikel auf dev.to bietet hervorragende Einblicke in die Frage, wie die Speicherzuweisung die serverlose Preisgestaltung beeinflusst.

Das Essen zum Mitnehmen ist einfach: Ihre Kosten skalieren mit Ihrer Reservierung, nicht nur mit Ihrer Nutzung. Wenn Sie in Forge 512 MB zuweisen, Ihr Code aber immer nur 200 MB benötigt, werden Ihnen diese ungenutzten 312 MB bei jeder Ausführung der Funktion in Rechnung gestellt. Die Verringerung dieser Lücke ist eine der effektivsten Möglichkeiten, Ihren Verbrauch in GB-Sekunden zu reduzieren.

So profilierst du den Speicher in Forge

Die Developer Console von Atlassian meldet die Anzahl der Aufrufe und die Erfolgsraten, bietet aber derzeit keine Metrik „Maximal verwendeter Arbeitsspeicher“ für erfolgreiche Aufrufe. Um die Wahrheit herauszufinden, musst du deinen Code mit folgenden Instrumenten instrumentieren RSS (Resident Set Size) über process.memoryUsage.rss ().

Spitzennutzung verfolgen

Um Ihre Speicheranforderungen zu verstehen, können Sie mithilfe einer einfachen Variablen auf Modulebene den RSS-Spitzenwert verfolgen, der während der Lebensdauer einer bestimmten Ausführungsumgebung beobachtet wurde.

// memProfile.js
let peakMemory = 0;

export const monMemUsage = (label = "Checkpoint") => {
  const mem = process.memoryUsage.rss();
  const memMB = Math.round(mem / 1024 / 1024);
  
  if (memMB > peakMemory) {
    peakMemory = memMB;
  }
  
  console.log(`[Memory] ${label} - Current: ${memMB}MB, Peak Observed: ${peakMemory}MB`);
};

Instrumentierung eines Resolvers

Um ein genaues Profil zu erhalten, rufen Sie den Monitor an den Ein- und Ausstiegspunkten Ihrer Resolver sowie nach allen speicherintensiven Vorgängen (wie dem Abrufen großer Datensätze aus der Jira-API) auf.

import Resolver from '@forge/resolver';
import { monMemUsage } from './memProfile';

const resolver = new Resolver();

resolver.define('getData', async (req) => {
  monMemUsage('Resolver Start');
  
  const data = await someHeavyApiCall();
  monMemUsage('Post API Fetch');
  
  const result = transformData(data);
  monMemUsage('Resolver End');
  
  return result;
});

export const handler = resolver.getDefinitions();

Den Umfang verstehen: Profiling pro Prozess

Es ist wichtig, sich daran zu erinnern, dass diese Speicherverfolgung pro Prozess. Wenn Ihre Forge-App mehrere Anfragen verarbeitet, verwendet die Forge-Plattform möglicherweise gleichzeitige Prozesse. Jeder Prozess behält seinen eigenen Status auf Modulebene in seinem eigenen Speicherplatz bei.

  • Konsolidierung: Da Sie keinen einzigen „globalen“ Peak für alle Benutzer erkennen können, sollten Sie Ihre Logs aggregieren, um die Verteilung der Peaks auf verschiedene Prozesse zu ermitteln.
  • Statistische Ausrichtung: Wenn Ihre Arbeitslast einheitlich ist, werden sich die Spitzen in den verschiedenen Prozessen irgendwann über einen ausreichend großen Probenraum verteilen.
  • Vorsicht vor dem „Schwarzen Schwan“: Seien Sie vorsichtig, wenn Ihre App selten Codepfade ausgeführt hat. In der Technik und im Risikomanagement sind diese bekannt als Schwarze Schwäne - Ereignisse, die selten auftreten, aber massive Auswirkungen haben. Zum Beispiel könnte eine Schaltfläche „Alle Daten exportieren“ 450 MB verbrauchen, auch wenn Ihre „typische“ Spitzenlast nur 180 MB beträgt. Wenn Sie die Optimierung nur auf der Grundlage der durchschnittlichen Nutzung vornehmen, stürzen diese seltenen Aufgaben mit OOM-Fehlern (Out-of-Memory) ab.

Bestimmung Ihrer „sicheren“ Zuteilung

Sobald Sie Ihre maximale Speicherauslastung durch Profiling identifiziert haben, besteht die Versuchung, Ihre Speicher MB in der manifest.yml so nah wie möglich an dieser Zahl. Eine zu enge Festlegung des Grenzwerts ist jedoch aus mehreren Gründen gefährlich:

  1. RSS im Vergleich zu Plattformbeschränkungen: process.memoryUsage.rss () ist eine interne Messung des Prozesses Node.js. Dies ist zwar die uns am nächsten liegende Metrik, entspricht aber nicht immer 1:1 den von der Forge-Plattform erzwungenen Gesamtlimits für die Speicherzuweisung.
  2. V8 Müllabfuhr: Die Speichernutzung von Node.js ist nicht statisch. Die V8-Engine kann die Speicherbereinigung verzögern, was zu vorübergehenden Spitzen bei der Speicherauslastung führt, die Ihren „normalen“ Höchstwert überschreiten.
  3. Spielraum für Wachstum: Auch wenn Ihr Code heute effizient ist, benötigen Sie einen Puffer für ungewöhnliche Datennutzlasten oder zukünftige kleinere Codeänderungen, die den Speicherbedarf leicht erhöhen könnten.

Die Staging- und Verifizierungsphase

Bevor neue Speichereinstellungen in der Produktion eingeführt werden, ist es wichtig, die Anwendung in einer Staging-Umgebung „backen“ zu lassen. In dieser Phase können Sie Ihre Annahmen anhand einer Vielzahl von Workloads überprüfen, ohne dass sich dies auf die Endbenutzer auswirkt.

  • Last simulieren: Führen Sie Ihre intensivsten Operationen mehrmals aus, um zu sehen, ob die maximale Speicherauslastung stabil bleibt oder ob sie bei Warmstarts ansteigt.
  • Überwachen Sie auf Fehler: Behalten Sie die Protokolle genau im Auge, wenn es um Out-of-Memory (OOM) -Fehler geht. Wenn beim Staging Abstürze auftreten, ist Ihr Headroom zu gering.
  • Überprüfen Sie „seltene“ Pfade: Triggern Sie diese selteneren Codepfade (die „Black Swans“) manuell, um sicherzustellen, dass sie weiterhin innerhalb der neuen vorgeschlagenen Grenzwerte ausgeführt werden können.

Fazit: Erzielung einer Kostenreduzierung von 40%

In unserer Profilerstellung stellten wir fest, dass unser Spitzen-RSS durchweg konstant blieb 180 MB für Standardoperationen. Unter Berücksichtigung der oben genannten Headroom-Faktoren und Messabweichungen entschieden wir uns für Speicher MB zu 300 MB in der manifest.yml.

Dies bot einen gesunden 120-MB-Puffer für Spitzen und lieferte gleichzeitig eine 40% Ermäßigung in unserem fakturierbaren Rechenaufwand im Vergleich zum Standard von 512 MB.

app:
  runtime:
    name: nodejs22.x
    memoryMB: 300 # Optimized from 512MB default

Durch die Kombination von gezielter Instrumentierung mit einem konservativen Puffer und einer strengen Staging-Phase können Sie Ihren Forge-Footprint getrost für die neue verbrauchsorientierte Welt optimieren. Implementieren Sie Ihre Änderungen, beobachten Sie die Protokolle und profitieren Sie von den Effizienzgewinnen.

Übernehmen Sie noch heute die Kontrolle über Ihre Daten