diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua
index aa2be2125ae46ad28318236a2445f29a642c219f..6d89aae153128cf870bda3c1464d249a9d451b09 100644
--- a/mods/default/furnace.lua
+++ b/mods/default/furnace.lua
@@ -90,137 +90,6 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
 	return stack:get_count()
 end
 
-local function swap_node(pos, name)
-	local node = minetest.get_node(pos)
-	if node.name == name then
-		return
-	end
-	node.name = name
-	minetest.swap_node(pos, node)
-end
-
-local function furnace_node_timer(pos, elapsed)
-	--
-	-- Inizialize metadata
-	--
-	local meta = minetest.get_meta(pos)
-	local fuel_time = meta:get_float("fuel_time") or 0
-	local src_time = meta:get_float("src_time") or 0
-	local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
-
-	local inv = meta:get_inventory()
-	local srclist = inv:get_list("src")
-	local fuellist = inv:get_list("fuel")
-	local dstlist = inv:get_list("dst")
-
-	--
-	-- Cooking
-	--
-
-	-- Check if we have cookable content
-	local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
-	local cookable = true
-
-	if cooked.time == 0 then
-		cookable = false
-	end
-
-	-- Check if we have enough fuel to burn
-	if fuel_time < fuel_totaltime then
-		-- The furnace is currently active and has enough fuel
-		fuel_time = fuel_time + 1
-
-		-- If there is a cookable item then check if it is ready yet
-		if cookable then
-			src_time = src_time + 1
-			if src_time >= cooked.time then
-				-- Place result in dst list if possible
-				if inv:room_for_item("dst", cooked.item) then
-					inv:add_item("dst", cooked.item)
-					inv:set_stack("src", 1, aftercooked.items[1])
-					src_time = 0
-				end
-			end
-		end
-	else
-		-- Furnace ran out of fuel
-		if cookable then
-			-- We need to get new fuel
-			local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
-
-			if fuel.time == 0 then
-				-- No valid fuel in fuel list
-				fuel_totaltime = 0
-				fuel_time = 0
-				src_time = 0
-			else
-				-- Take fuel from fuel list
-				inv:set_stack("fuel", 1, afterfuel.items[1])
-
-				fuel_totaltime = fuel.time
-				fuel_time = 0
-			end
-		else
-			-- We don't need to get new fuel since there is no cookable item
-			fuel_totaltime = 0
-			fuel_time = 0
-			src_time = 0
-		end
-	end
-
-	--
-	-- Update formspec, infotext and node
-	--
-	local formspec = inactive_formspec
-	local item_state = ""
-	local item_percent = 0
-	if cookable then
-		item_percent = math.floor(src_time / cooked.time * 100)
-		item_state = item_percent .. "%"
-	else
-		if srclist[1]:is_empty() then
-			item_state = "Empty"
-		else
-			item_state = "Not cookable"
-		end
-	end
-
-	local fuel_state = "Empty"
-	local active = "inactive "
-	local result = false
-
-	if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
-		active = "active "
-		local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
-		fuel_state = fuel_percent .. "%"
-		formspec = active_formspec(fuel_percent, item_percent)
-		swap_node(pos, "default:furnace_active")
-		-- make sure timer restarts automatically
-		result = true
-	else
-		if not fuellist[1]:is_empty() then
-			fuel_state = "0%"
-		end
-		swap_node(pos, "default:furnace")
-		-- stop timer on the inactive furnace
-		local timer = minetest.get_node_timer(pos)
-		timer:stop()
-	end
-
-	local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
-
-	--
-	-- Set meta values
-	--
-	meta:set_float("fuel_totaltime", fuel_totaltime)
-	meta:set_float("fuel_time", fuel_time)
-	meta:set_float("src_time", src_time)
-	meta:set_string("formspec", formspec)
-	meta:set_string("infotext", infotext)
-
-	return result
-end
-
 --
 -- Node definitions
 --
@@ -237,26 +106,9 @@ minetest.register_node("default:furnace", {
 	legacy_facedir_simple = true,
 	is_ground_content = false,
 	sounds = default.node_sound_stone_defaults(),
-
+	
 	can_dig = can_dig,
-
-	on_timer = furnace_node_timer,
-
-	on_construct = function(pos)
-		local meta = minetest.get_meta(pos)
-		meta:set_string("formspec", inactive_formspec)
-		local inv = meta:get_inventory()
-		inv:set_size('src', 1)
-		inv:set_size('fuel', 1)
-		inv:set_size('dst', 4)
-	end,
-
-	on_metadata_inventory_put = function(pos)
-		-- start timer function, it will sort out whether furnace can burn or not.
-		local timer = minetest.get_node_timer(pos)
-		timer:start(1.0)
-	end,
-
+	
 	allow_metadata_inventory_put = allow_metadata_inventory_put,
 	allow_metadata_inventory_move = allow_metadata_inventory_move,
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
@@ -286,12 +138,154 @@ minetest.register_node("default:furnace_active", {
 	legacy_facedir_simple = true,
 	is_ground_content = false,
 	sounds = default.node_sound_stone_defaults(),
-	on_timer = furnace_node_timer,
-
+	
 	can_dig = can_dig,
-
+	
 	allow_metadata_inventory_put = allow_metadata_inventory_put,
 	allow_metadata_inventory_move = allow_metadata_inventory_move,
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
 })
 
+--
+-- ABM
+--
+
+local function swap_node(pos, name)
+	local node = minetest.get_node(pos)
+	if node.name == name then
+		return
+	end
+	node.name = name
+	minetest.swap_node(pos, node)
+end
+
+minetest.register_abm({
+	nodenames = {"default:furnace", "default:furnace_active"},
+	interval = 1.0,
+	chance = 1,
+	action = function(pos, node, active_object_count, active_object_count_wider)
+		--
+		-- Inizialize metadata
+		--
+		local meta = minetest.get_meta(pos)
+		local fuel_time = meta:get_float("fuel_time") or 0
+		local src_time = meta:get_float("src_time") or 0
+		local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
+		
+		--
+		-- Inizialize inventory
+		--
+		local inv = meta:get_inventory()
+		for listname, size in pairs({
+				src = 1,
+				fuel = 1,
+				dst = 4,
+		}) do
+			if inv:get_size(listname) ~= size then
+				inv:set_size(listname, size)
+			end
+		end
+		local srclist = inv:get_list("src")
+		local fuellist = inv:get_list("fuel")
+		local dstlist = inv:get_list("dst")
+		
+		--
+		-- Cooking
+		--
+		
+		-- Check if we have cookable content
+		local cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
+		local cookable = true
+		
+		if cooked.time == 0 then
+			cookable = false
+		end
+		
+		-- Check if we have enough fuel to burn
+		if fuel_time < fuel_totaltime then
+			-- The furnace is currently active and has enough fuel
+			fuel_time = fuel_time + 1
+			
+			-- If there is a cookable item then check if it is ready yet
+			if cookable then
+				src_time = src_time + 1
+				if src_time >= cooked.time then
+					-- Place result in dst list if possible
+					if inv:room_for_item("dst", cooked.item) then
+						inv:add_item("dst", cooked.item)
+						inv:set_stack("src", 1, aftercooked.items[1])
+						src_time = 0
+					end
+				end
+			end
+		else
+			-- Furnace ran out of fuel
+			if cookable then
+				-- We need to get new fuel
+				local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
+				
+				if fuel.time == 0 then
+					-- No valid fuel in fuel list
+					fuel_totaltime = 0
+					fuel_time = 0
+					src_time = 0
+				else
+					-- Take fuel from fuel list
+					inv:set_stack("fuel", 1, afterfuel.items[1])
+					
+					fuel_totaltime = fuel.time
+					fuel_time = 0
+					
+				end
+			else
+				-- We don't need to get new fuel since there is no cookable item
+				fuel_totaltime = 0
+				fuel_time = 0
+				src_time = 0
+			end
+		end
+		
+		--
+		-- Update formspec, infotext and node
+		--
+		local formspec = inactive_formspec
+		local item_state = ""
+		local item_percent = 0
+		if cookable then
+			item_percent =  math.floor(src_time / cooked.time * 100)
+			item_state = item_percent .. "%"
+		else
+			if srclist[1]:is_empty() then
+				item_state = "Empty"
+			else
+				item_state = "Not cookable"
+			end
+		end
+		
+		local fuel_state = "Empty"
+		local active = "inactive "
+		if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
+			active = "active "
+			local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
+			fuel_state = fuel_percent .. "%"
+			formspec = active_formspec(fuel_percent, item_percent)
+			swap_node(pos, "default:furnace_active")
+		else
+			if not fuellist[1]:is_empty() then
+				fuel_state = "0%"
+			end
+			swap_node(pos, "default:furnace")
+		end
+		
+		local infotext =  "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")"
+		
+		--
+		-- Set meta values
+		--
+		meta:set_float("fuel_totaltime", fuel_totaltime)
+		meta:set_float("fuel_time", fuel_time)
+		meta:set_float("src_time", src_time)
+		meta:set_string("formspec", formspec)
+		meta:set_string("infotext", infotext)
+	end,
+})