diff --git a/sharedstate.lua b/sharedstate.lua
index bfa7a71..d9a60f9 100644
--- a/sharedstate.lua
+++ b/sharedstate.lua
@@ -5,6 +5,10 @@ local logging=require((...):gsub("(.)$", "%1.") .. 'logging')
 local is_initialized, callback_value, set_value,
 get_value, resolve_key, resolve_index
 
+-- list of "dirty" keys that are queued for sync. This table should be
+-- accessible to the entirety of the sharedstate library
+local state_queued={}
+
 -- we're protecting internal variables here, i'm *that* scared of writing bad
 -- code again.
 -- this section is purely for making sure the tables are in a consistent state
@@ -19,7 +23,7 @@ do
 	local state_table={}
 
 	-- schema: {1: key_name_for_val_1, ...}
-	-- this is to save bandwidth in pings, 
+	-- this is to save bandwidth in pings
 	local state_map={}
 
 	--- Check if initialized
@@ -171,6 +175,23 @@ function sharedstate.set(key, value)
 	-- pings.sharedstate_ktransfer(key, value)
 end
 
+---Send queued entries
+--Send queued table entries to other hosts in one ping.
+function sharedstate.send()
+	--schema: similar to state_table, nested table only contains value
+	local send_queue={}
+	-- this is intentional values in state_queued are key names
+	for _, key in pairs(state_queued) do
+		local t={
+			["value"]=get_value(key)
+		}
+		send_queue[key]=t
+	end
+
+	pings.sharedstate_unpack(send_queue)
+	state_queued={}
+end
+
 -- this can be copied directly from the internal functions as it is read only
 sharedstate.get=get_value