diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 19f7e3016b3358e049fff4b902e636b4b3ce5379..97d12c6634395d0412bbab1a32728dfb32a6ac46 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -387,6 +387,8 @@ public class ModelConfig {
 	public static final int NUM_YIELD_CLUSTERS = getIntProperty("NUM_YIELD_CLUSTERS", 8000);
 	public static final long RANDOM_SEED = getIntProperty("RANDOM_SEED", 1974329);  // any number will do
 
+	public static final String CHECKPOINT_YEARS = getProperty("CHECKPOINT_YEARS", null); // 2020,2050
+
 	// Protected areas forcing parameters
 	public static final boolean FORCE_PROTECTED_AREAS = IS_CALIBRATION_RUN ? false : getBooleanProperty("FORCE_PROTECTED_AREAS", false);
 	public static final int FORCE_PROTECTED_AREAS_START_YEAR  = getIntProperty("FORCE_PROTECTED_AREAS_START_YEAR", 2020);
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index 5d41efaeffd4d2caccbed0dc0444ad2252baa0b7..f863419d2876475169095e08ba695da2c51d4bb9 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -143,6 +143,24 @@ public class ModelMain {
 		
 		// output results
 		outputTimestepResults(timestep, globalLandUseRaster);
+		
+		checkAndSaveCheckpoint(timestep);
+	}
+
+	private void checkAndSaveCheckpoint(Timestep timestep) {
+		if (ModelConfig.CHECKPOINT_YEARS != null) {
+			LogWriter.println("Looking to see if checkpoint year reached " + ModelConfig.CHECKPOINT_YEARS);
+
+			String[] yearStr = ModelConfig.CHECKPOINT_YEARS.split(",");
+			for(int i=0; i<yearStr.length; i++) {
+				LogWriter.println("Got a checkpoint yearStr " + yearStr[i]);
+				int year = Integer.parseInt(yearStr[i]);
+				if (timestep.getYear() == year) {
+					LogWriter.println("Saving checkpoint");
+					serializeCheckpoint(globalLandUseRaster);
+				}
+			}
+		}
 	}
 
 	private void writeLandCoverFile(Timestep timestep, RasterSet<LandUseItem> landUseRaster) {
@@ -424,9 +442,7 @@ public class ModelMain {
 		}
 
 		if (ModelConfig.IS_CALIBRATION_RUN) {
-			serializeLandUse(landUseRaster);
-			countryAgents.serializeCropUsageForAll();
-			internationalMarket.serializeGlobalPrices();
+			serializeCheckpoint(landUseRaster);
 		}
 
 		if (timestep.isInitialTimestep() && ModelConfig.GENERATE_NEW_YIELD_CLUSTERS)
@@ -629,4 +645,10 @@ public class ModelMain {
 			currentIrrigationData.updateIrrigConstraints(timestep);
 		}
 	}	
+	
+	private void serializeCheckpoint(RasterSet<LandUseItem> landUseRaster) {
+		serializeLandUse(landUseRaster);
+		countryAgents.serializeCropUsageForAll();
+		internationalMarket.serializeGlobalPrices();
+	}
 }