FTP vs SFTP Tutorial: How to Actually Use Both
This is the hands-on tutorial — how to actually connect to a server, upload files, and automate transfers using both FTP and SFTP. Side-by-side examples in FileZilla, the CLI, and a Python script, so you can pick the right protocol and tooling for your workflow.
If you already know the protocol-level differences between FTP and SFTP and just want to know how to actually use them, this post is the hands-on tutorial. We cover three ways to connect with each protocol — through FileZilla (the graphical client most teams use), through the OS-bundled command-line clients, and through a Python automation script — with side-by-side examples so you can see the same operation done both ways. For the protocol-level comparison, see our FTP vs FTPS vs SFTP explainer; for the decision framework, see the FTP vs SFTP decision guide.
Before you start: what you'll need
- An FTP or SFTP server you can connect to. If you don't have one, start a free Files.com trial — provisioned in about 10 minutes with both FTP and SFTP endpoints on the same backend storage.
- Credentials. For FTP, a username and password. For SFTP, either a username and password or an SSH key pair.
- The relevant client. FileZilla (free, cross-platform) is the easiest graphical client. The OS-bundled
ftpandsftpcommands ship on macOS, Linux, and modern Windows.
The example server in this tutorial is sftp.example.com running on default ports (21 for FTP, 22 for SFTP). Substitute your own server's hostname.
1. Connecting with FileZilla
FileZilla is the most widely used graphical FTP/SFTP client. The connection flow is similar for both protocols — only the protocol dropdown and credentials change.
Open the Site Manager (File → Site Manager) and create a new site.
For FTP:
- Protocol:
FTP - File Transfer Protocol - Host:
sftp.example.com - Port:
21(leave blank for default) - Encryption:
Use explicit FTP over TLS if available(this gets you FTPS, which is what you almost always want — pure unencrypted FTP only for legacy systems) - Logon Type:
Normal - User / Password: your FTP credentials
For SFTP:
- Protocol:
SFTP - SSH File Transfer Protocol - Host:
sftp.example.com - Port:
22 - Logon Type:
Normal(for password) orKey file(for SSH key authentication) - User: your SFTP username
- Password / Key file: your password or the path to your private key (
~/.ssh/id_ed25519)
Click Connect. The left pane shows your local filesystem; the right pane shows the remote server. Drag files between them to upload or download. Right-click on either pane for additional operations (rename, delete, permissions, refresh).
If the connection fails:
- "Connection refused" — wrong port, or the protocol is blocked by your firewall. Try the alternate protocol on its own port.
- "Authentication failed" — wrong credentials. For SFTP, also check that the public key matches what's on the server.
- "Could not connect to server" with FTP only — almost always a passive-mode issue. Switch the transfer mode to passive (or vice versa) in
Edit → Settings → Connection → FTP → Transfer Mode. See our active vs passive FTP explainer.
2. Connecting from the command line
Both protocols ship with command-line clients on every modern OS.
FTP via the ftp command:
$ ftp ftp.example.com
Connected to ftp.example.com.
220 Welcome
Name (ftp.example.com:alice): alice
331 Password required
Password: ********
230 Login successful
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection
report-2026-05.csv
forecast.xlsx
226 Transfer complete
ftp> get report-2026-05.csv
local: report-2026-05.csv remote: report-2026-05.csv
200 PORT command successful
150 Opening BINARY mode data connection
226 Transfer complete
ftp> put forecast-v2.xlsx
200 PORT command successful
150 Opening BINARY mode data connection
226 Transfer complete
ftp> bye
221 Goodbye
SFTP via the sftp command:
$ sftp alice@sftp.example.com
The authenticity of host 'sftp.example.com (10.0.0.5)' can't be established.
ED25519 key fingerprint is SHA256:abc123...
Are you sure you want to continue connecting? yes
alice@sftp.example.com's password: ********
Connected to sftp.example.com.
sftp> ls
report-2026-05.csv forecast.xlsx
sftp> get report-2026-05.csv
Fetching /home/alice/report-2026-05.csv to report-2026-05.csv
100% 142KB 142.0KB/s 00:00
sftp> put forecast-v2.xlsx
Uploading forecast-v2.xlsx to /home/alice/forecast-v2.xlsx
100% 54KB 54.0KB/s 00:00
sftp> bye
Command equivalents:
| Operation | FTP | SFTP |
|---|---|---|
| Change directory | cd /reports | cd /reports |
| List files | ls or dir | ls |
| Download a file | get file.csv | get file.csv |
| Upload a file | put file.csv | put file.csv |
| Multiple files | mget *.csv | mget *.csv |
| Make directory | mkdir reports | mkdir reports |
| Show working dir | pwd | pwd |
| Disconnect | bye or quit | bye or quit |
The command sets are deliberately similar; learn one, and the other is mostly the same. The protocol difference is in how the connection is established, not in how you operate it once connected.
Using SSH keys with sftp:
# Generate a keypair (one-time setup)
ssh-keygen -t ed25519 -C "alice@laptop"
# Install the public key on the server (one-time setup)
ssh-copy-id alice@sftp.example.com
# Connect — no password required
sftp alice@sftp.example.com
See our setting-up-ssh-keys guide for the full walkthrough.
3. Automating transfers in Python
For scheduled or scripted transfers, both protocols have mature Python libraries.
FTP with the standard library (ftplib):
from ftplib import FTP_TLS
with FTP_TLS("ftp.example.com") as ftp:
ftp.login(user="alice", passwd="********")
ftp.prot_p() # enable TLS for data channel
ftp.cwd("/reports")
# Download
with open("report-2026-05.csv", "wb") as f:
ftp.retrbinary("RETR report-2026-05.csv", f.write)
# Upload
with open("forecast.xlsx", "rb") as f:
ftp.storbinary("STOR forecast.xlsx", f)
FTP_TLS is the FTPS variant — encrypted from the start. Use plain FTP only for unencrypted legacy systems.
SFTP with Paramiko:
import paramiko
# Connect with SSH key authentication
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
"sftp.example.com",
username="alice",
key_filename="/home/alice/.ssh/id_ed25519",
)
sftp = ssh.open_sftp()
sftp.chdir("/reports")
# Download
sftp.get("report-2026-05.csv", "report-2026-05.csv")
# Upload
sftp.put("forecast.xlsx", "forecast.xlsx")
sftp.close()
ssh.close()
Both libraries are mature, well-documented, and supported across every Python version still in use. For one-off scripts, the standard library's ftplib is enough; for production automation involving SFTP, Paramiko is the universal choice.
Common gotchas worth knowing about
- Binary vs ASCII transfer mode in FTP. FTP's ASCII mode translates
\r\nline endings on transfer; binary mode passes bytes through unchanged. ASCII mode corrupts non-text files. Force binary mode (binaryin the CLI, orstorbinary/retrbinaryinftplib) for anything that isn't a plain text file. SFTP has no equivalent — it's binary-only. - Filename encoding. Old FTP servers often use Latin-1; SFTP standardized on UTF-8. Filenames with accents, em-dashes, or non-Latin characters can transfer cleanly under one and break under the other.
- Connection persistence. FTP control connections often time out after 5–15 minutes of idle. SFTP sessions are SSH sessions and follow SSH's keepalive settings. For long-running batch transfers, set up client-side keepalives (
KeepAlive yesin~/.ssh/config, orftp.set_pasv(True)+ periodic NOOP commands inftplib). - Server-side passive port range. FTP passive-mode data connections need a port range open on the server's firewall. If you can log in and list files but downloads hang, this is almost certainly the cause. See our active vs passive FTP explainer.
- Host key changes for SFTP. If you reinstall a server, its SSH host key changes, and
sftpwill refuse to connect to "the same hostname with a different identity." Remove the old entry withssh-keygen -R sftp.example.comto re-trust on next connection.
The modern way
Files.com is the File Orchestration Platform we'd recommend for any team running FTP / SFTP workflows in 2026. It exposes both protocols (plus FTPS and WebDAV) on the same backend storage, so the question "FTP or SFTP" becomes "which client does the partner already have." Beyond the protocol layer:
- Per-user SSH key auth for SFTP, auto-managed TLS for FTPS. No cipher hygiene or certificate rotation on your side.
- REST API and SDKs in 8 languages for automation that doesn't want to deal with raw
ftplibor Paramiko. - Audit logging on every transfer. Per-file, per-user, queryable in the dashboard.
- SOC 2 Type II and HIPAA-BAA out of the box.
Start a free Files.com trial — no credit card, provisioned in about 10 minutes.
For teams that must run file-transfer infrastructure inside their own datacenter, the free ExaVault on-premise appliance handles both protocols from a self-hosted VM image.
FAQ
Can I use the same client for both FTP and SFTP?
Yes. FileZilla, WinSCP, Cyberduck, and Transmit all support both protocols. The protocol choice is a dropdown in the connection dialog; the rest of the workflow looks the same.
Will my existing FTP scripts work with SFTP?
Probably not, without changes. The CLI tools have similar commands (get, put, cd, ls) but the binaries differ (ftp vs sftp) and the Python libraries are different (ftplib vs paramiko). Automation needs to be ported, not just reconfigured. The good news: the structural shape of the script — "connect, cd, list, transfer, disconnect" — translates directly.
What's the fastest way to test if my server supports FTP, SFTP, or both?
From any modern shell:
nc -vz server.example.com 21 # FTP control port
nc -vz server.example.com 22 # SSH/SFTP port
nc -vz server.example.com 990 # implicit FTPS port
nc (netcat) reports "succeeded" if the port is accepting connections. That tells you which protocols are listening; the actual login is a separate test.
How do I transfer multiple files at once?
In the CLI, mget *.csv (multiple get) and mput *.csv (multiple put) handle wildcards. In FileZilla, select multiple files in the file list and drag them across. In a Python script, loop over a list of filenames calling get / put for each.
Can I resume an interrupted FTP or SFTP transfer?
Yes for both, but the mechanics differ. FTP uses the REST command to set a restart point; most clients handle this automatically when configured to. SFTP supports native partial-file reads and writes — clients like FileZilla and Cyberduck pick up interrupted transfers transparently. CLI sftp supports reget and reput for explicit resume.
What's the difference between SSH and FTP?
They're different protocols entirely. SSH is a general-purpose secure-shell protocol — you log into a remote machine and run commands as if you were sitting at it. FTP is a file-transfer protocol — log into a server and move files around, but you can't run arbitrary commands. SFTP is the bridge: it uses SSH for transport but exposes file operations only, not full shell access.