Skip to main content

How to Create a Self-Destructing File Timer in Python

Sometimes you need a file, like a session token, temporary configuration, or sensitive data, to exist for only a limited time before being automatically deleted.

This guide demonstrates how to build a robust file monitor that watches a specific file and deletes it after a configurable expiration time.

Basic Implementation

We use pathlib for modern file handling and configparser for external configuration.

Configuration File

Create a config.ini file to control the deletion timing:

[Security]
delete_after_minutes = 5

Monitor Script

import time
import configparser
from pathlib import Path


def monitor_and_delete(target_file: str, config_file: str) -> None:
"""
Monitor a file and delete it after the configured expiry time.

Args:
target_file: Path to the file to monitor
config_file: Path to the configuration file
"""
file_path = Path(target_file)
config = configparser.ConfigParser()
config.read(config_file)

# Get expiry time with fallback default
minutes = config.getint("Security", "delete_after_minutes", fallback=1)
limit_seconds = minutes * 60

start_time = time.time()
print(f"Monitoring: {file_path}")
print(f"Expiry: {minutes} minute(s)")

while True:
# Exit if file was manually deleted
if not file_path.exists():
print("File no longer exists. Exiting monitor.")
break

elapsed = time.time() - start_time
remaining = limit_seconds - elapsed

# Check if time has expired
if remaining <= 0:
try:
file_path.unlink()
print(f"File '{target_file}' deleted after {minutes} minute(s).")
except PermissionError:
print("Error: Permission denied. File may be in use.")
except OSError as e:
print(f"Error deleting file: {e}")
break

# Sleep to prevent CPU waste
time.sleep(5)


if __name__ == "__main__":
# Create a test file
test_file = Path("secret.txt")
test_file.write_text("Top Secret Data")

monitor_and_delete("secret.txt", "config.ini")

Output:

Monitoring: secret.txt
Expiry: 1 minute(s)
File 'secret.txt' deleted after 1 minute(s).

Enhanced Version with Logging and Callbacks

For production use, add logging and optional callbacks:

import time
import configparser
import logging
from pathlib import Path
from typing import Callable, Optional
from datetime import datetime, timedelta

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)


class SelfDestructingFile:
"""Monitor a file and delete it after a specified duration."""

def __init__(
self,
target_file: str,
minutes: int = 5,
on_delete: Optional[Callable[[Path], None]] = None,
check_interval: int = 5
):
self.file_path = Path(target_file)
self.duration = timedelta(minutes=minutes)
self.on_delete = on_delete
self.check_interval = check_interval
self.start_time: Optional[datetime] = None

def start_monitoring(self) -> bool:
"""
Start monitoring the file.

Returns:
True if file was deleted, False if file disappeared
"""
if not self.file_path.exists():
logger.error(f"File not found: {self.file_path}")
return False

self.start_time = datetime.now()
expiry_time = self.start_time + self.duration

logger.info(f"Monitoring: {self.file_path}")
logger.info(f"Scheduled deletion: {expiry_time.strftime('%H:%M:%S')}")

while True:
if not self.file_path.exists():
logger.warning("File was removed externally. Stopping monitor.")
return False

if datetime.now() >= expiry_time:
return self._delete_file()

time.sleep(self.check_interval)

def _delete_file(self) -> bool:
"""Attempt to delete the file."""
try:
self.file_path.unlink()
logger.info(f"Successfully deleted: {self.file_path}")

if self.on_delete:
self.on_delete(self.file_path)

return True

except PermissionError:
logger.error("Permission denied. File may be locked.")
return False
except OSError as e:
logger.error(f"Failed to delete file: {e}")
return False


def on_file_deleted(file_path: Path) -> None:
"""Callback executed after file deletion."""
logger.info(f"Cleanup complete for: {file_path}")


if __name__ == "__main__":
# Create test file
test_file = Path("sensitive_data.txt")
test_file.write_text("This will self-destruct!")

monitor = SelfDestructingFile(
target_file="sensitive_data.txt",
minutes=1,
on_delete=on_file_deleted,
check_interval=5
)

monitor.start_monitoring()

Output:

2026-02-14 10:44:48,471 - INFO - Monitoring: sensitive_data.txt
2026-02-14 10:44:48,471 - INFO - Scheduled deletion: 10:45:48
2026-02-14 10:45:48,473 - INFO - Successfully deleted: sensitive_data.txt
2026-02-14 10:45:48,473 - INFO - Cleanup complete for: sensitive_data.txt

Running as a Background Thread

To monitor files without blocking your main application:

import threading
import time
from pathlib import Path


def background_monitor(file_path: str, seconds: int) -> None:
"""Monitor and delete a file in a background thread."""
path = Path(file_path)
time.sleep(seconds)

if path.exists():
try:
path.unlink()
print(f"Background: Deleted {file_path}")
except OSError as e:
print(f"Background: Failed to delete - {e}")


def create_temp_file(filename: str, content: str, lifetime_seconds: int) -> Path:
"""
Create a temporary file that self-destructs after a duration.

Args:
filename: Name of the file to create
content: Content to write to the file
lifetime_seconds: How long the file should exist

Returns:
Path to the created file
"""
path = Path(filename)
path.write_text(content)

# Start background deletion thread
thread = threading.Thread(
target=background_monitor,
args=(filename, lifetime_seconds),
daemon=True
)
thread.start()

return path


if __name__ == "__main__":
# Create a file that deletes itself after 30 seconds
temp_file = create_temp_file(
filename="session_token.txt",
content="abc123xyz",
lifetime_seconds=30
)

print(f"Created: {temp_file}")
print("File will self-destruct in 30 seconds...")

# Main program continues
time.sleep(35)
print(f"File exists: {temp_file.exists()}")

Output:

Created: session_token.txt
File will self-destruct in 30 seconds...
Background: Deleted session_token.txt
File exists: False

Best Practices

CPU Efficiency

Always include time.sleep() in monitoring loops. Without it, the script would consume 100% of a CPU core checking conditions millions of times per second.

File Locking

On Windows especially, files may be locked by other programs. Always wrap deletion in try-except blocks to handle PermissionError gracefully.

Key Recommendations

PracticeReason
Use configparser or .envAvoid hardcoding durations; enable policy changes without code edits
Add sleep intervalsPrevent CPU waste in monitoring loops
Handle exceptionsFiles may be locked or already deleted
Use pathlib.PathModern, cross-platform file handling
Log operationsTrack when files are created and deleted
Use daemon threadsEnsure threads don't prevent program exit

Summary

  • Use pathlib.Path.unlink() for cross-platform file deletion.
  • Always sleep in monitoring loops to prevent CPU waste.
  • Handle PermissionError for files that may be locked.
  • Use external configuration files for flexible timing policies.
  • Consider background threads for non-blocking monitoring.