diff --git a/src/ipa/simple/algorithms/agc.cpp b/src/ipa/simple/algorithms/agc.cpp
index cdde56ba2..3c0e20ddc 100644
--- a/src/ipa/simple/algorithms/agc.cpp
+++ b/src/ipa/simple/algorithms/agc.cpp
@@ -41,7 +41,15 @@ Agc::Agc()
 {
 }
 
-void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, double exposureMSV)
+int Agc::configure(IPAContext &context,
+		   [[maybe_unused]] const IPAConfigInfo &configInfo)
+{
+	context.activeState.agc.skipFrames = 0;
+
+	return 0;
+}
+
+void Agc::updateExposure(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, double exposureMSV)
 {
 	/*
 	 * kExpDenominator of 10 gives ~10% increment/decrement;
@@ -51,8 +59,18 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
 	static constexpr uint8_t kExpNumeratorUp = kExpDenominator + 1;
 	static constexpr uint8_t kExpNumeratorDown = kExpDenominator - 1;
 
-	int32_t &exposure = frameContext.sensor.exposure;
-	double &again = frameContext.sensor.gain;
+	int32_t &skipFrames = context.activeState.agc.skipFrames;
+	int32_t &exposure = context.activeState.agc.exposure;
+	double &again = context.activeState.agc.again;
+
+	/* Set initial-gain values from sensor on first frame */
+	if (frame == 0) {
+		exposure = frameContext.sensor.exposure;
+		again = frameContext.sensor.gain;
+	}
+
+	if (skipFrames && --skipFrames)
+		return;
 
 	if (exposureMSV < kExposureOptimal - kExposureSatisfactory) {
 		if (exposure < context.configuration.agc.exposureMax) {
@@ -68,6 +86,7 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
 			else
 				again = next;
 		}
+		skipFrames = 3;
 	}
 
 	if (exposureMSV > kExposureOptimal + kExposureSatisfactory) {
@@ -84,6 +103,7 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
 			else
 				exposure = next;
 		}
+		skipFrames = 3;
 	}
 
 	exposure = std::clamp(exposure, context.configuration.agc.exposureMin,
@@ -97,7 +117,7 @@ void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
 }
 
 void Agc::process(IPAContext &context,
-		  [[maybe_unused]] const uint32_t frame,
+		  const uint32_t frame,
 		  IPAFrameContext &frameContext,
 		  const SwIspStats *stats,
 		  ControlList &metadata)
@@ -135,7 +155,7 @@ void Agc::process(IPAContext &context,
 	}
 
 	float exposureMSV = (denom == 0 ? 0 : static_cast<float>(num) / denom);
-	updateExposure(context, frameContext, exposureMSV);
+	updateExposure(context, frame, frameContext, exposureMSV);
 }
 
 REGISTER_IPA_ALGORITHM(Agc, "Agc")
diff --git a/src/ipa/simple/algorithms/agc.h b/src/ipa/simple/algorithms/agc.h
index 112d9f5a1..ef387664f 100644
--- a/src/ipa/simple/algorithms/agc.h
+++ b/src/ipa/simple/algorithms/agc.h
@@ -19,13 +19,14 @@ public:
 	Agc();
 	~Agc() = default;
 
+	int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
 	void process(IPAContext &context, const uint32_t frame,
 		     IPAFrameContext &frameContext,
 		     const SwIspStats *stats,
 		     ControlList &metadata) override;
 
 private:
-	void updateExposure(IPAContext &context, IPAFrameContext &frameContext, double exposureMSV);
+	void updateExposure(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, double exposureMSV);
 };
 
 } /* namespace ipa::soft::algorithms */
diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h
index ba525a881..cdab980a1 100644
--- a/src/ipa/simple/ipa_context.h
+++ b/src/ipa/simple/ipa_context.h
@@ -37,6 +37,12 @@ struct IPASessionConfiguration {
 };
 
 struct IPAActiveState {
+	struct {
+		int32_t skipFrames;
+		int32_t exposure;
+		double again;
+	} agc;
+
 	struct {
 		uint8_t level;
 		int32_t lastExposure;
diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
index f0764ef46..f8c6291e2 100644
--- a/src/ipa/simple/soft_simple.cpp
+++ b/src/ipa/simple/soft_simple.cpp
@@ -327,8 +327,8 @@ void IPASoftSimple::processStats(const uint32_t frame,
 
 	ControlList ctrls(sensorInfoMap_);
 
-	auto &againNew = frameContext.sensor.gain;
-	ctrls.set(V4L2_CID_EXPOSURE, frameContext.sensor.exposure);
+	auto &againNew = context_.activeState.agc.again;
+	ctrls.set(V4L2_CID_EXPOSURE, context_.activeState.agc.exposure);
 	ctrls.set(V4L2_CID_ANALOGUE_GAIN,
 		  static_cast<int32_t>(camHelper_ ? camHelper_->gainCode(againNew) : againNew));
 
