diff --git a/src/tarantool.rs b/src/tarantool.rs
index 5d9224d72d30c6152ab6e3b6493204b6162be48a..4dc880f785a1f4c207773f8d254a7bd039b7ff67 100644
--- a/src/tarantool.rs
+++ b/src/tarantool.rs
@@ -5,7 +5,7 @@ use std::time::Instant;
 use ::tarantool::fiber;
 use ::tarantool::lua_state;
 use ::tarantool::net_box;
-use ::tarantool::tlua::{self, LuaError, LuaFunction, LuaTable};
+use ::tarantool::tlua::{self, LuaError, LuaFunction, LuaRead, LuaTable, LuaThread, PushGuard};
 pub use ::tarantool::trigger::on_shutdown;
 use ::tarantool::tuple::ToTupleBuffer;
 
@@ -162,6 +162,33 @@ pub fn set_cfg(cfg: &Cfg) {
     box_cfg.call_with_args(cfg).unwrap()
 }
 
+#[allow(dead_code)]
+pub fn cfg_field<T>(field: &str) -> Option<T>
+where
+    T: LuaRead<PushGuard<LuaTable<PushGuard<LuaTable<PushGuard<LuaThread>>>>>>,
+{
+    let l = lua_state();
+    let b: LuaTable<_> = l.into_get("box").ok()?;
+    let cfg: LuaTable<_> = b.into_get("cfg").ok()?;
+    cfg.into_get(field).ok()
+}
+
+pub fn set_cfg_field<T>(field: &str, value: T) -> Result<(), tlua::LuaError>
+where
+    T: tlua::PushOneInto<tlua::LuaState>,
+    tlua::Void: From<T::Err>,
+{
+    use tlua::{Call, CallError};
+
+    let l = lua_state();
+    let b: LuaTable<_> = l.get("box").expect("can't fail under tarantool");
+    let cfg: tlua::Callable<_> = b.get("cfg").expect("can't fail under tarantool");
+    cfg.call_with([(field, value)]).map_err(|e| match e {
+        CallError::PushError(_) => unreachable!("cannot fail during push"),
+        CallError::LuaError(e) => e,
+    })
+}
+
 #[track_caller]
 pub fn exec(code: &str) -> Result<(), LuaError> {
     let l = lua_state();